From 1dcf6c5447bcfcdb7be51486c4a147232e71f21a Mon Sep 17 00:00:00 2001 From: Kowalski Date: Wed, 11 Feb 2026 14:36:01 +0100 Subject: [PATCH] =?UTF-8?q?Prvn=C3=AD=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 14 + .htaccess | 1 + .vscode/sftp.json | 21 + app/Bootstrap.php | 51 + app/Core/AppPresenter.php | 26 + app/Core/Funkce.php | 238 + app/Core/MujAutentifikator.php | 86 + app/Core/MujAutorizator.php | 106 + app/Core/RouterFactory.php | 21 + app/Core/TwoFactorService.php | 69 + app/Model/FormData/CteckaFormData.php | 15 + app/Model/FormData/FotoFormData.php | 22 + app/Model/FormData/LoginFormData.php | 14 + app/Model/FormData/NavstevaFormData.php | 25 + app/Model/Login/ServerCredentials.php | 48 + app/Model/Login/UserIdentity.php | 30 + app/Model/UzivatelFacade.php | 58 + app/Presentation/@layout.latte | 108 + app/Presentation/Accessory/LatteExtension.php | 22 + .../Disable2fa/Disable2faPresenter.php | 76 + app/Presentation/Disable2fa/default.latte | 64 + app/Presentation/Error/Error4xx/403.latte | 7 + app/Presentation/Error/Error4xx/404.latte | 8 + app/Presentation/Error/Error4xx/410.latte | 6 + app/Presentation/Error/Error4xx/4xx.latte | 6 + .../Error/Error4xx/Error4xxPresenter.php | 27 + app/Presentation/Error/Error5xx/500.phtml | 27 + app/Presentation/Error/Error5xx/503.phtml | 24 + .../Error/Error5xx/Error5xxPresenter.php | 39 + app/Presentation/Home/HomePresenter.php | 13 + app/Presentation/Home/default.latte | 49 + .../Setup2fa/Setup2faPresenter.php | 122 + app/Presentation/Setup2fa/default.latte | 82 + app/Presentation/Sign/SignPresenter.php | 160 + app/Presentation/Sign/in.latte | 22 + app/Presentation/Sign/twoFactor.latte | 72 + assets/main.js | 4 + composer.json | 46 + composer.lock | 2172 +++ config/common.neon | 35 + config/services.neon | 12 + latte-lint | 18 + package.json | 14 + readme.md | 64 + vendor/autoload.php | 25 + vendor/bacon/bacon-qr-code/LICENSE | 22 + vendor/bacon/bacon-qr-code/README.md | 62 + vendor/bacon/bacon-qr-code/composer.json | 51 + .../bacon-qr-code/src/Common/BitArray.php | 364 + .../bacon-qr-code/src/Common/BitMatrix.php | 307 + .../bacon-qr-code/src/Common/BitUtils.php | 41 + .../src/Common/CharacterSetEci.php | 177 + .../bacon-qr-code/src/Common/EcBlock.php | 33 + .../bacon-qr-code/src/Common/EcBlocks.php | 66 + .../src/Common/ErrorCorrectionLevel.php | 57 + .../src/Common/FormatInformation.php | 196 + .../bacon/bacon-qr-code/src/Common/Mode.php | 69 + .../src/Common/ReedSolomonCodec.php | 454 + .../bacon-qr-code/src/Common/Version.php | 592 + .../bacon-qr-code/src/Encoder/BlockPair.php | 44 + .../bacon-qr-code/src/Encoder/ByteMatrix.php | 134 + .../bacon-qr-code/src/Encoder/Encoder.php | 666 + .../bacon-qr-code/src/Encoder/MaskUtil.php | 271 + .../bacon-qr-code/src/Encoder/MatrixUtil.php | 513 + .../bacon-qr-code/src/Encoder/QrCode.php | 108 + .../src/Exception/ExceptionInterface.php | 10 + .../Exception/InvalidArgumentException.php | 8 + .../src/Exception/OutOfBoundsException.php | 8 + .../src/Exception/RuntimeException.php | 8 + .../Exception/UnexpectedValueException.php | 8 + .../src/Exception/WriterException.php | 8 + .../src/Renderer/Color/Alpha.php | 44 + .../bacon-qr-code/src/Renderer/Color/Cmyk.php | 82 + .../src/Renderer/Color/ColorInterface.php | 22 + .../bacon-qr-code/src/Renderer/Color/Gray.php | 39 + .../bacon-qr-code/src/Renderer/Color/Rgb.php | 73 + .../src/Renderer/Eye/CompositeEye.php | 26 + .../src/Renderer/Eye/EyeInterface.php | 26 + .../src/Renderer/Eye/ModuleEye.php | 48 + .../src/Renderer/Eye/PointyEye.php | 56 + .../src/Renderer/Eye/SimpleCircleEye.php | 51 + .../src/Renderer/Eye/SquareEye.php | 50 + .../src/Renderer/GDLibRenderer.php | 237 + .../src/Renderer/Image/EpsImageBackEnd.php | 373 + .../Renderer/Image/ImageBackEndInterface.php | 87 + .../Renderer/Image/ImagickImageBackEnd.php | 318 + .../src/Renderer/Image/SvgImageBackEnd.php | 363 + .../Renderer/Image/TransformationMatrix.php | 68 + .../src/Renderer/ImageRenderer.php | 150 + .../src/Renderer/Module/DotsModule.php | 56 + .../src/Renderer/Module/EdgeIterator/Edge.php | 82 + .../Module/EdgeIterator/EdgeIterator.php | 160 + .../src/Renderer/Module/ModuleInterface.php | 18 + .../src/Renderer/Module/RoundnessModule.php | 124 + .../src/Renderer/Module/SquareModule.php | 44 + .../bacon-qr-code/src/Renderer/Path/Close.php | 34 + .../bacon-qr-code/src/Renderer/Path/Curve.php | 86 + .../src/Renderer/Path/EllipticArc.php | 264 + .../bacon-qr-code/src/Renderer/Path/Line.php | 42 + .../bacon-qr-code/src/Renderer/Path/Move.php | 42 + .../src/Renderer/Path/OperationInterface.php | 17 + .../bacon-qr-code/src/Renderer/Path/Path.php | 117 + .../src/Renderer/PlainTextRenderer.php | 80 + .../src/Renderer/RendererInterface.php | 11 + .../src/Renderer/RendererStyle/EyeFill.php | 61 + .../src/Renderer/RendererStyle/Fill.php | 129 + .../src/Renderer/RendererStyle/Gradient.php | 31 + .../Renderer/RendererStyle/GradientType.php | 22 + .../Renderer/RendererStyle/RendererStyle.php | 69 + vendor/bacon/bacon-qr-code/src/Writer.php | 63 + vendor/bin/latte-lint | 119 + vendor/bin/latte-lint.bat | 5 + vendor/bin/neon-lint | 119 + vendor/bin/neon-lint.bat | 5 + vendor/bin/phpstan | 119 + vendor/bin/phpstan.bat | 5 + vendor/bin/phpstan.phar | 119 + vendor/bin/phpstan.phar.bat | 5 + vendor/bin/tester | 119 + vendor/bin/tester.bat | 5 + vendor/composer/ClassLoader.php | 579 + vendor/composer/InstalledVersions.php | 359 + vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 696 + vendor/composer/autoload_files.php | 12 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 22 + vendor/composer/autoload_real.php | 50 + vendor/composer/autoload_static.php | 831 ++ vendor/composer/installed.json | 2251 ++++ vendor/composer/installed.php | 293 + vendor/composer/platform_check.php | 26 + vendor/dasprid/enum/LICENSE | 22 + vendor/dasprid/enum/README.md | 164 + vendor/dasprid/enum/composer.json | 34 + vendor/dasprid/enum/src/AbstractEnum.php | 261 + vendor/dasprid/enum/src/EnumMap.php | 385 + .../Exception/CloneNotSupportedException.php | 10 + .../enum/src/Exception/ExceptionInterface.php | 10 + .../src/Exception/ExpectationException.php | 10 + .../Exception/IllegalArgumentException.php | 10 + .../enum/src/Exception/MismatchException.php | 10 + .../SerializeNotSupportedException.php | 10 + .../UnserializeNotSupportedException.php | 10 + vendor/dasprid/enum/src/NullValue.php | 75 + vendor/endroid/qr-code/LICENSE | 19 + vendor/endroid/qr-code/README.md | 230 + vendor/endroid/qr-code/assets/open_sans.ttf | Bin 0 -> 217360 bytes vendor/endroid/qr-code/composer.json | 54 + .../Bacon/ErrorCorrectionLevelConverter.php | 21 + .../qr-code/src/Bacon/MatrixFactory.php | 32 + .../endroid/qr-code/src/Builder/Builder.php | 128 + .../qr-code/src/Builder/BuilderInterface.php | 45 + .../qr-code/src/Builder/BuilderRegistry.php | 25 + .../src/Builder/BuilderRegistryInterface.php | 12 + vendor/endroid/qr-code/src/Color/Color.php | 56 + .../qr-code/src/Color/ColorInterface.php | 23 + .../endroid/qr-code/src/Encoding/Encoding.php | 27 + .../src/Encoding/EncodingInterface.php | 10 + .../qr-code/src/ErrorCorrectionLevel.php | 13 + .../Exception/BlockSizeTooSmallException.php | 9 + .../src/Exception/ValidationException.php | 23 + .../qr-code/src/ImageData/LabelImageData.php | 48 + .../qr-code/src/ImageData/LogoImageData.php | 159 + .../endroid/qr-code/src/Label/Font/Font.php | 32 + .../qr-code/src/Label/Font/FontInterface.php | 12 + .../qr-code/src/Label/Font/OpenSans.php | 23 + vendor/endroid/qr-code/src/Label/Label.php | 49 + .../qr-code/src/Label/LabelAlignment.php | 12 + .../qr-code/src/Label/LabelInterface.php | 22 + .../qr-code/src/Label/Margin/Margin.php | 47 + .../src/Label/Margin/MarginInterface.php | 19 + vendor/endroid/qr-code/src/Logo/Logo.php | 36 + .../qr-code/src/Logo/LogoInterface.php | 16 + vendor/endroid/qr-code/src/Matrix/Matrix.php | 91 + .../src/Matrix/MatrixFactoryInterface.php | 12 + .../qr-code/src/Matrix/MatrixInterface.php | 22 + vendor/endroid/qr-code/src/QrCode.php | 65 + .../endroid/qr-code/src/QrCodeInterface.php | 27 + .../qr-code/src/RoundBlockSizeMode.php | 13 + .../qr-code/src/Writer/AbstractGdWriter.php | 211 + .../qr-code/src/Writer/BinaryWriter.php | 23 + .../qr-code/src/Writer/ConsoleWriter.php | 23 + .../qr-code/src/Writer/DebugWriter.php | 32 + .../endroid/qr-code/src/Writer/EpsWriter.php | 44 + .../endroid/qr-code/src/Writer/GifWriter.php | 23 + .../endroid/qr-code/src/Writer/PdfWriter.php | 139 + .../endroid/qr-code/src/Writer/PngWriter.php | 43 + .../src/Writer/Result/AbstractResult.php | 31 + .../src/Writer/Result/BinaryResult.php | 35 + .../src/Writer/Result/ConsoleResult.php | 69 + .../qr-code/src/Writer/Result/DebugResult.php | 74 + .../qr-code/src/Writer/Result/EpsResult.php | 28 + .../qr-code/src/Writer/Result/GdResult.php | 32 + .../qr-code/src/Writer/Result/GifResult.php | 21 + .../qr-code/src/Writer/Result/PdfResult.php | 32 + .../qr-code/src/Writer/Result/PngResult.php | 35 + .../src/Writer/Result/ResultInterface.php | 20 + .../qr-code/src/Writer/Result/SvgResult.php | 43 + .../qr-code/src/Writer/Result/WebPResult.php | 35 + .../endroid/qr-code/src/Writer/SvgWriter.php | 174 + .../src/Writer/ValidatingWriterInterface.php | 12 + .../endroid/qr-code/src/Writer/WebPWriter.php | 29 + .../qr-code/src/Writer/WriterInterface.php | 16 + vendor/latte/latte/bin/latte-lint | 42 + vendor/latte/latte/composer.json | 58 + vendor/latte/latte/license.md | 60 + vendor/latte/latte/readme.md | 39 + .../src/Bridges/Tracy/BlueScreenPanel.php | 98 + .../latte/src/Bridges/Tracy/LattePanel.php | 123 + .../src/Bridges/Tracy/TracyExtension.php | 37 + .../latte/src/Bridges/Tracy/dist/panel.phtml | 96 + .../latte/src/Bridges/Tracy/dist/tab.phtml | 12 + .../latte/latte/src/Bridges/Tracy/panel.latte | 94 + .../latte/latte/src/Bridges/Tracy/tab.latte | 8 + vendor/latte/latte/src/Latte/Cache.php | 142 + .../latte/latte/src/Latte/Compiler/Block.php | 41 + .../latte/src/Latte/Compiler/Escaper.php | 253 + .../latte/latte/src/Latte/Compiler/Node.php | 21 + .../latte/src/Latte/Compiler/NodeHelpers.php | 129 + .../src/Latte/Compiler/NodeTraverser.php | 81 + .../src/Latte/Compiler/Nodes/AreaNode.php | 17 + .../Latte/Compiler/Nodes/AuxiliaryNode.php | 41 + .../src/Latte/Compiler/Nodes/FragmentNode.php | 72 + .../Compiler/Nodes/Html/AttributeNode.php | 57 + .../Compiler/Nodes/Html/BogusTagNode.php | 46 + .../Latte/Compiler/Nodes/Html/CommentNode.php | 39 + .../Latte/Compiler/Nodes/Html/ElementNode.php | 124 + .../Nodes/Html/ExpressionAttributeNode.php | 58 + .../src/Latte/Compiler/Nodes/Html/TagNode.php | 72 + .../src/Latte/Compiler/Nodes/NopNode.php | 27 + .../Latte/Compiler/Nodes/Php/ArgumentNode.php | 51 + .../Compiler/Nodes/Php/ArrayItemNode.php | 62 + .../Compiler/Nodes/Php/ClosureUseNode.php | 38 + .../Compiler/Nodes/Php/ComplexTypeNode.php | 17 + .../Nodes/Php/Expression/ArrayAccessNode.php | 41 + .../Nodes/Php/Expression/ArrayNode.php | 51 + .../Nodes/Php/Expression/AssignNode.php | 65 + .../Nodes/Php/Expression/AssignOpNode.php | 66 + .../Nodes/Php/Expression/AuxiliaryNode.php | 42 + .../Nodes/Php/Expression/BinaryOpNode.php | 93 + .../Nodes/Php/Expression/CastNode.php | 50 + .../Php/Expression/ClassConstantFetchNode.php | 42 + .../Nodes/Php/Expression/CloneNode.php | 43 + .../Nodes/Php/Expression/ClosureNode.php | 77 + .../Php/Expression/ConstantFetchNode.php | 45 + .../Nodes/Php/Expression/EmptyNode.php | 36 + .../Nodes/Php/Expression/FilterCallNode.php | 44 + .../Nodes/Php/Expression/FunctionCallNode.php | 53 + .../Compiler/Nodes/Php/Expression/InNode.php | 42 + .../Nodes/Php/Expression/InstanceofNode.php | 48 + .../Nodes/Php/Expression/IssetNode.php | 56 + .../Nodes/Php/Expression/MatchNode.php | 51 + .../Nodes/Php/Expression/MethodCallNode.php | 62 + .../Compiler/Nodes/Php/Expression/NewNode.php | 54 + .../Nodes/Php/Expression/PostOpNode.php | 61 + .../Nodes/Php/Expression/PreOpNode.php | 61 + .../Php/Expression/PropertyFetchNode.php | 42 + .../Php/Expression/StaticMethodCallNode.php | 63 + .../Expression/StaticPropertyFetchNode.php | 42 + .../Nodes/Php/Expression/TemporaryNode.php | 38 + .../Nodes/Php/Expression/TernaryNode.php | 54 + .../Nodes/Php/Expression/UnaryOpNode.php | 54 + .../Nodes/Php/Expression/VariableNode.php | 40 + .../Compiler/Nodes/Php/ExpressionNode.php | 41 + .../Latte/Compiler/Nodes/Php/FilterNode.php | 86 + .../Compiler/Nodes/Php/IdentifierNode.php | 42 + .../Nodes/Php/InterpolatedStringPartNode.php | 36 + .../Nodes/Php/IntersectionTypeNode.php | 41 + .../Latte/Compiler/Nodes/Php/ListItemNode.php | 48 + .../src/Latte/Compiler/Nodes/Php/ListNode.php | 56 + .../Latte/Compiler/Nodes/Php/MatchArmNode.php | 47 + .../Latte/Compiler/Nodes/Php/ModifierNode.php | 94 + .../src/Latte/Compiler/Nodes/Php/NameNode.php | 89 + .../Compiler/Nodes/Php/NullableTypeNode.php | 35 + .../Latte/Compiler/Nodes/Php/OperatorNode.php | 29 + .../Compiler/Nodes/Php/ParameterNode.php | 54 + .../Compiler/Nodes/Php/Scalar/BooleanNode.php | 30 + .../Compiler/Nodes/Php/Scalar/FloatNode.php | 65 + .../Compiler/Nodes/Php/Scalar/IntegerNode.php | 71 + .../Php/Scalar/InterpolatedStringNode.php | 77 + .../Compiler/Nodes/Php/Scalar/NullNode.php | 29 + .../Compiler/Nodes/Php/Scalar/StringNode.php | 41 + .../Latte/Compiler/Nodes/Php/ScalarNode.php | 19 + .../Compiler/Nodes/Php/SuperiorTypeNode.php | 35 + .../Compiler/Nodes/Php/UnionTypeNode.php | 41 + .../Nodes/Php/VarLikeIdentifierNode.php | 21 + .../Nodes/Php/VariadicPlaceholderNode.php | 35 + .../src/Latte/Compiler/Nodes/PrintNode.php | 60 + .../Latte/Compiler/Nodes/StatementNode.php | 15 + .../src/Latte/Compiler/Nodes/TemplateNode.php | 34 + .../src/Latte/Compiler/Nodes/TextNode.php | 44 + .../latte/src/Latte/Compiler/PhpHelpers.php | 263 + .../latte/src/Latte/Compiler/Position.php | 47 + .../latte/src/Latte/Compiler/PrintContext.php | 288 + vendor/latte/latte/src/Latte/Compiler/Tag.php | 117 + .../latte/src/Latte/Compiler/TagLexer.php | 401 + .../latte/src/Latte/Compiler/TagParser.php | 475 + .../src/Latte/Compiler/TagParserData.php | 633 + .../src/Latte/Compiler/TemplateGenerator.php | 218 + .../src/Latte/Compiler/TemplateLexer.php | 329 + .../src/Latte/Compiler/TemplateParser.php | 456 + .../src/Latte/Compiler/TemplateParserHtml.php | 617 + .../latte/latte/src/Latte/Compiler/Token.php | 263 + .../latte/src/Latte/Compiler/TokenStream.php | 136 + vendor/latte/latte/src/Latte/ContentType.php | 22 + vendor/latte/latte/src/Latte/Engine.php | 583 + .../src/Latte/Essential/AuxiliaryIterator.php | 48 + .../latte/src/Latte/Essential/Blueprint.php | 184 + .../src/Latte/Essential/CachingIterator.php | 229 + .../src/Latte/Essential/CoreExtension.php | 287 + .../latte/src/Latte/Essential/Filters.php | 775 ++ .../src/Latte/Essential/Nodes/BlockNode.php | 159 + .../src/Latte/Essential/Nodes/CaptureNode.php | 87 + .../Latte/Essential/Nodes/ContentTypeNode.php | 87 + .../Nodes/CustomFunctionCallNode.php | 48 + .../Latte/Essential/Nodes/DebugbreakNode.php | 53 + .../src/Latte/Essential/Nodes/DefineNode.php | 136 + .../src/Latte/Essential/Nodes/DoNode.php | 61 + .../src/Latte/Essential/Nodes/DumpNode.php | 58 + .../src/Latte/Essential/Nodes/EmbedNode.php | 126 + .../src/Latte/Essential/Nodes/ExtendsNode.php | 57 + .../Essential/Nodes/FirstLastSepNode.php | 81 + .../src/Latte/Essential/Nodes/ForNode.php | 94 + .../src/Latte/Essential/Nodes/ForeachNode.php | 183 + .../Latte/Essential/Nodes/IfChangedNode.php | 141 + .../Latte/Essential/Nodes/IfContentNode.php | 85 + .../src/Latte/Essential/Nodes/IfNode.php | 185 + .../src/Latte/Essential/Nodes/ImportNode.php | 55 + .../Essential/Nodes/IncludeBlockNode.php | 141 + .../Latte/Essential/Nodes/IncludeFileNode.php | 80 + .../Essential/Nodes/IterateWhileNode.php | 96 + .../src/Latte/Essential/Nodes/JumpNode.php | 88 + .../src/Latte/Essential/Nodes/NAttrNode.php | 95 + .../src/Latte/Essential/Nodes/NClassNode.php | 54 + .../src/Latte/Essential/Nodes/NElseNode.php | 120 + .../src/Latte/Essential/Nodes/NTagNode.php | 47 + .../Latte/Essential/Nodes/ParametersNode.php | 87 + .../src/Latte/Essential/Nodes/RawPhpNode.php | 53 + .../Latte/Essential/Nodes/RollbackNode.php | 43 + .../Latte/Essential/Nodes/SpacelessNode.php | 62 + .../src/Latte/Essential/Nodes/SwitchNode.php | 118 + .../Essential/Nodes/TemplatePrintNode.php | 68 + .../Essential/Nodes/TemplateTypeNode.php | 44 + .../src/Latte/Essential/Nodes/TraceNode.php | 41 + .../Latte/Essential/Nodes/TranslateNode.php | 105 + .../src/Latte/Essential/Nodes/TryNode.php | 74 + .../src/Latte/Essential/Nodes/VarNode.php | 105 + .../Latte/Essential/Nodes/VarPrintNode.php | 53 + .../src/Latte/Essential/Nodes/VarTypeNode.php | 42 + .../src/Latte/Essential/Nodes/WhileNode.php | 81 + .../latte/src/Latte/Essential/Passes.php | 123 + .../src/Latte/Essential/RawPhpExtension.php | 26 + .../src/Latte/Essential/RollbackException.php | 16 + .../latte/src/Latte/Essential/Tracer.php | 106 + .../Latte/Essential/TranslatorExtension.php | 107 + vendor/latte/latte/src/Latte/Extension.php | 99 + vendor/latte/latte/src/Latte/Helpers.php | 140 + vendor/latte/latte/src/Latte/Loader.php | 32 + .../latte/src/Latte/Loaders/FileLoader.php | 84 + .../latte/src/Latte/Loaders/StringLoader.php | 68 + vendor/latte/latte/src/Latte/Policy.php | 24 + .../src/Latte/PositionAwareException.php | 47 + .../latte/latte/src/Latte/Runtime/Block.php | 20 + .../src/Latte/Runtime/FilterExecutor.php | 145 + .../latte/src/Latte/Runtime/FilterInfo.php | 38 + .../src/Latte/Runtime/FunctionExecutor.php | 69 + .../latte/latte/src/Latte/Runtime/Helpers.php | 93 + vendor/latte/latte/src/Latte/Runtime/Html.php | 31 + .../latte/src/Latte/Runtime/HtmlHelpers.php | 374 + .../src/Latte/Runtime/HtmlStringable.php | 17 + .../latte/src/Latte/Runtime/Template.php | 382 + .../latte/src/Latte/Runtime/XmlHelpers.php | 110 + .../Latte/Sandbox/Nodes/FunctionCallNode.php | 32 + .../Latte/Sandbox/Nodes/MethodCallNode.php | 36 + .../Latte/Sandbox/Nodes/PropertyFetchNode.php | 32 + .../src/Latte/Sandbox/Nodes/SandboxNode.php | 73 + .../Sandbox/Nodes/StaticMethodCallNode.php | 35 + .../Sandbox/Nodes/StaticPropertyFetchNode.php | 32 + .../src/Latte/Sandbox/RuntimeChecker.php | 115 + .../src/Latte/Sandbox/SandboxExtension.php | 139 + .../src/Latte/Sandbox/SecurityPolicy.php | 184 + vendor/latte/latte/src/Latte/attributes.php | 24 + vendor/latte/latte/src/Latte/exceptions.php | 71 + vendor/latte/latte/src/Tools/Linter.php | 193 + .../latte/latte/src/Tools/LinterExtension.php | 157 + vendor/nette/application/.phpstorm.meta.php | 66 + vendor/nette/application/composer.json | 64 + vendor/nette/application/license.md | 60 + vendor/nette/application/readme.md | 13 + .../src/Application/Application.php | 236 + .../Application/Attributes/CrossOrigin.php | 26 + .../src/Application/Attributes/Deprecated.php | 17 + .../src/Application/Attributes/Parameter.php | 21 + .../src/Application/Attributes/Persistent.php | 24 + .../src/Application/Attributes/Requires.php | 32 + .../Attributes/TemplateVariable.php | 21 + .../src/Application/ErrorPresenter.php | 44 + .../application/src/Application/Helpers.php | 54 + .../src/Application/IPresenter.php | 19 + .../src/Application/IPresenterFactory.php | 28 + .../src/Application/LinkGenerator.php | 319 + .../src/Application/MicroPresenter.php | 159 + .../src/Application/PresenterFactory.php | 138 + .../application/src/Application/Request.php | 191 + .../application/src/Application/Response.php | 27 + .../Responses/CallbackResponse.php | 40 + .../Application/Responses/FileResponse.php | 126 + .../Application/Responses/ForwardResponse.php | 41 + .../Application/Responses/JsonResponse.php | 54 + .../Responses/RedirectResponse.php | 51 + .../Application/Responses/TextResponse.php | 47 + .../Application/Responses/VoidResponse.php | 23 + .../src/Application/Routers/CliRouter.php | 109 + .../src/Application/Routers/Route.php | 193 + .../src/Application/Routers/RouteList.php | 145 + .../src/Application/Routers/SimpleRouter.php | 44 + .../src/Application/UI/AccessPolicy.php | 135 + .../src/Application/UI/BadSignalException.php | 22 + .../src/Application/UI/Component.php | 384 + .../Application/UI/ComponentReflection.php | 239 + .../src/Application/UI/Control.php | 167 + .../application/src/Application/UI/Form.php | 159 + .../Application/UI/InvalidLinkException.php | 18 + .../application/src/Application/UI/Link.php | 89 + .../src/Application/UI/MethodReflection.php | 35 + .../src/Application/UI/Multiplier.php | 34 + .../src/Application/UI/ParameterConverter.php | 191 + .../src/Application/UI/Presenter.php | 1180 ++ .../src/Application/UI/Renderable.php | 30 + .../src/Application/UI/SignalReceiver.php | 22 + .../src/Application/UI/StatePersistent.php | 30 + .../src/Application/UI/Template.php | 35 + .../src/Application/UI/TemplateFactory.php | 22 + .../src/Application/exceptions.php | 75 + .../src/Application/templates/error.phtml | 50 + .../ApplicationDI/ApplicationExtension.php | 292 + .../Bridges/ApplicationDI/LatteExtension.php | 178 + .../PresenterFactoryCallback.php | 65 + .../ApplicationDI/RoutingExtension.php | 104 + .../ApplicationLatte/DefaultTemplate.php | 52 + .../Bridges/ApplicationLatte/LatteFactory.php | 21 + .../ApplicationLatte/Nodes/ControlNode.php | 142 + .../ApplicationLatte/Nodes/IfCurrentNode.php | 70 + .../ApplicationLatte/Nodes/LinkBaseNode.php | 83 + .../ApplicationLatte/Nodes/LinkNode.php | 92 + .../ApplicationLatte/Nodes/NNonceNode.php | 37 + .../Nodes/SnippetAreaNode.php | 88 + .../ApplicationLatte/Nodes/SnippetNode.php | 169 + .../Nodes/TemplatePrintNode.php | 61 + .../ApplicationLatte/SnippetBridge.php | 95 + .../ApplicationLatte/SnippetRuntime.php | 144 + .../src/Bridges/ApplicationLatte/Template.php | 150 + .../ApplicationLatte/TemplateFactory.php | 151 + .../Bridges/ApplicationLatte/UIExtension.php | 141 + .../src/Bridges/ApplicationLatte/UIMacros.php | 187 + .../Bridges/ApplicationLatte/UIRuntime.php | 84 + .../Bridges/ApplicationTracy/RoutingPanel.php | 145 + .../Bridges/ApplicationTracy/dist/panel.phtml | 185 + .../Bridges/ApplicationTracy/dist/tab.phtml | 20 + .../src/Bridges/ApplicationTracy/panel.latte | 181 + .../src/Bridges/ApplicationTracy/tab.latte | 16 + .../application/src/compatibility-intf.php | 88 + .../nette/application/src/compatibility.php | 28 + vendor/nette/assets/composer.json | 49 + vendor/nette/assets/license.md | 60 + vendor/nette/assets/readme.md | 1115 ++ vendor/nette/assets/src/Assets/Asset.php | 22 + vendor/nette/assets/src/Assets/AudioAsset.php | 59 + vendor/nette/assets/src/Assets/EntryAsset.php | 25 + .../assets/src/Assets/FilesystemMapper.php | 98 + vendor/nette/assets/src/Assets/FontAsset.php | 52 + .../nette/assets/src/Assets/GenericAsset.php | 33 + vendor/nette/assets/src/Assets/Helpers.php | 127 + .../assets/src/Assets/HtmlRenderable.php | 24 + vendor/nette/assets/src/Assets/ImageAsset.php | 88 + vendor/nette/assets/src/Assets/LazyLoad.php | 42 + vendor/nette/assets/src/Assets/Mapper.php | 19 + vendor/nette/assets/src/Assets/Registry.php | 110 + .../nette/assets/src/Assets/ScriptAsset.php | 58 + vendor/nette/assets/src/Assets/StyleAsset.php | 54 + vendor/nette/assets/src/Assets/VideoAsset.php | 58 + vendor/nette/assets/src/Assets/ViteMapper.php | 163 + vendor/nette/assets/src/Assets/exceptions.php | 21 + .../src/Bridges/AssetsDI/DIExtension.php | 155 + .../Bridges/AssetsLatte/LatteExtension.php | 57 + .../Bridges/AssetsLatte/Nodes/AssetNode.php | 71 + .../Bridges/AssetsLatte/Nodes/NAssetNode.php | 107 + .../src/Bridges/AssetsLatte/Runtime.php | 140 + vendor/nette/bootstrap/composer.json | 60 + vendor/nette/bootstrap/config.stub.neon | 11 + vendor/nette/bootstrap/license.md | 60 + vendor/nette/bootstrap/readme.md | 30 + .../bootstrap/src/Bootstrap/Configurator.php | 374 + .../Extensions/ConstantsExtension.php | 36 + .../src/Bootstrap/Extensions/PhpExtension.php | 42 + vendor/nette/bootstrap/src/Configurator.php | 19 + vendor/nette/caching/composer.json | 51 + vendor/nette/caching/license.md | 60 + vendor/nette/caching/readme.md | 398 + .../src/Bridges/CacheDI/CacheExtension.php | 57 + .../src/Bridges/CacheLatte/CacheExtension.php | 75 + .../Bridges/CacheLatte/Nodes/CacheNode.php | 70 + .../src/Bridges/CacheLatte/Runtime.php | 99 + .../src/Bridges/Psr/PsrCacheAdapter.php | 116 + .../nette/caching/src/Caching/BulkReader.php | 26 + .../nette/caching/src/Caching/BulkWriter.php | 28 + vendor/nette/caching/src/Caching/Cache.php | 436 + .../caching/src/Caching/OutputHelper.php | 55 + vendor/nette/caching/src/Caching/Storage.php | 46 + .../src/Caching/Storages/DevNullStorage.php | 44 + .../src/Caching/Storages/FileStorage.php | 376 + .../caching/src/Caching/Storages/Journal.php | 31 + .../src/Caching/Storages/MemcachedStorage.php | 231 + .../src/Caching/Storages/MemoryStorage.php | 52 + .../src/Caching/Storages/SQLiteJournal.php | 145 + .../src/Caching/Storages/SQLiteStorage.php | 148 + vendor/nette/caching/src/compatibility.php | 39 + .../nette/component-model/.phpstorm.meta.php | 7 + vendor/nette/component-model/composer.json | 42 + vendor/nette/component-model/license.md | 60 + vendor/nette/component-model/readme.md | 31 + .../src/ComponentModel/ArrayAccess.php | 67 + .../src/ComponentModel/Component.php | 306 + .../src/ComponentModel/Container.php | 261 + .../src/ComponentModel/IComponent.php | 35 + .../src/ComponentModel/IContainer.php | 42 + .../RecursiveComponentIterator.php | 46 + vendor/nette/database/composer.json | 47 + vendor/nette/database/license.md | 60 + vendor/nette/database/readme.md | 141 + .../Bridges/DatabaseDI/DatabaseExtension.php | 140 + .../Bridges/DatabaseTracy/ConnectionPanel.php | 163 + .../Bridges/DatabaseTracy/dist/panel.phtml | 83 + .../src/Bridges/DatabaseTracy/dist/tab.phtml | 13 + .../src/Bridges/DatabaseTracy/panel.latte | 71 + .../src/Bridges/DatabaseTracy/tab.latte | 6 + .../database/src/Database/Connection.php | 368 + .../database/src/Database/Conventions.php | 47 + .../AmbiguousReferenceKeyException.php | 18 + .../Conventions/DiscoveredConventions.php | 100 + .../Conventions/StaticConventions.php | 72 + .../nette/database/src/Database/DateTime.php | 34 + vendor/nette/database/src/Database/Driver.php | 102 + .../database/src/Database/DriverException.php | 65 + .../src/Database/Drivers/MsSqlDriver.php | 246 + .../src/Database/Drivers/MySqlDriver.php | 232 + .../src/Database/Drivers/OciDriver.php | 144 + .../src/Database/Drivers/OdbcDriver.php | 114 + .../src/Database/Drivers/PgSqlDriver.php | 264 + .../src/Database/Drivers/SqliteDriver.php | 255 + .../src/Database/Drivers/SqlsrvDriver.php | 256 + .../nette/database/src/Database/Explorer.php | 211 + .../nette/database/src/Database/Helpers.php | 405 + vendor/nette/database/src/Database/IRow.php | 16 + .../database/src/Database/IRowContainer.php | 16 + .../database/src/Database/IStructure.php | 78 + .../database/src/Database/Reflection.php | 102 + .../src/Database/Reflection/Column.php | 38 + .../src/Database/Reflection/ForeignKey.php | 34 + .../src/Database/Reflection/Index.php | 33 + .../src/Database/Reflection/Table.php | 120 + .../nette/database/src/Database/ResultSet.php | 271 + vendor/nette/database/src/Database/Row.php | 65 + .../database/src/Database/SqlLiteral.php | 41 + .../database/src/Database/SqlPreprocessor.php | 357 + .../nette/database/src/Database/Structure.php | 263 + .../database/src/Database/Table/ActiveRow.php | 297 + .../src/Database/Table/GroupedSelection.php | 285 + .../database/src/Database/Table/IRow.php | 18 + .../src/Database/Table/IRowContainer.php | 18 + .../database/src/Database/Table/Selection.php | 1072 ++ .../src/Database/Table/SqlBuilder.php | 877 ++ .../database/src/Database/exceptions.php | 50 + .../nette/database/src/compatibility-intf.php | 28 + vendor/nette/database/src/compatibility.php | 19 + vendor/nette/di/.phpstorm.meta.php | 8 + vendor/nette/di/composer.json | 48 + vendor/nette/di/license.md | 60 + vendor/nette/di/readme.md | 364 + .../di/src/Bridges/DITracy/ContainerPanel.php | 83 + .../di/src/Bridges/DITracy/dist/panel.phtml | 87 + .../di/src/Bridges/DITracy/dist/tab.phtml | 10 + .../nette/di/src/Bridges/DITracy/panel.latte | 84 + vendor/nette/di/src/Bridges/DITracy/tab.latte | 6 + vendor/nette/di/src/DI/Attributes/Inject.php | 18 + vendor/nette/di/src/DI/Autowiring.php | 164 + vendor/nette/di/src/DI/Compiler.php | 316 + vendor/nette/di/src/DI/CompilerExtension.php | 171 + vendor/nette/di/src/DI/Config/Adapter.php | 25 + .../di/src/DI/Config/Adapters/NeonAdapter.php | 244 + .../di/src/DI/Config/Adapters/PhpAdapter.php | 36 + vendor/nette/di/src/DI/Config/Helpers.php | 44 + vendor/nette/di/src/DI/Config/Loader.php | 122 + vendor/nette/di/src/DI/Container.php | 387 + vendor/nette/di/src/DI/ContainerBuilder.php | 407 + vendor/nette/di/src/DI/ContainerLoader.php | 114 + .../src/DI/Definitions/AccessorDefinition.php | 129 + .../di/src/DI/Definitions/Definition.php | 182 + .../src/DI/Definitions/FactoryDefinition.php | 231 + .../src/DI/Definitions/ImportedDefinition.php | 44 + .../src/DI/Definitions/LocatorDefinition.php | 177 + .../nette/di/src/DI/Definitions/Reference.php | 64 + .../src/DI/Definitions/ServiceDefinition.php | 229 + .../nette/di/src/DI/Definitions/Statement.php | 69 + vendor/nette/di/src/DI/DependencyChecker.php | 191 + vendor/nette/di/src/DI/DynamicParameter.php | 20 + .../di/src/DI/Extensions/DIExtension.php | 141 + .../src/DI/Extensions/DecoratorExtension.php | 88 + .../di/src/DI/Extensions/DefinitionSchema.php | 233 + .../src/DI/Extensions/ExtensionsExtension.php | 49 + .../di/src/DI/Extensions/InjectExtension.php | 173 + .../src/DI/Extensions/ParametersExtension.php | 103 + .../di/src/DI/Extensions/SearchExtension.php | 160 + .../src/DI/Extensions/ServicesExtension.php | 261 + vendor/nette/di/src/DI/Helpers.php | 287 + vendor/nette/di/src/DI/PhpGenerator.php | 203 + vendor/nette/di/src/DI/Resolver.php | 664 + vendor/nette/di/src/DI/exceptions.php | 49 + vendor/nette/di/src/compatibility.php | 39 + vendor/nette/forms/.phpstorm.meta.php | 8 + vendor/nette/forms/composer.json | 53 + vendor/nette/forms/eslint.config.js | 32 + vendor/nette/forms/examples/assets/logo.png | Bin 0 -> 1346 bytes vendor/nette/forms/examples/assets/style.css | 72 + vendor/nette/forms/examples/basic-example.php | 132 + .../forms/examples/bootstrap4-rendering.php | 107 + .../forms/examples/bootstrap5-rendering.php | 112 + vendor/nette/forms/examples/containers.php | 64 + .../nette/forms/examples/custom-control.php | 137 + .../nette/forms/examples/custom-rendering.php | 127 + .../nette/forms/examples/custom-validator.php | 64 + vendor/nette/forms/examples/html5.php | 63 + vendor/nette/forms/examples/latte.php | 62 + .../examples/latte/form-bootstrap5.latte | 66 + vendor/nette/forms/examples/latte/form.latte | 37 + vendor/nette/forms/examples/latte/page.latte | 19 + .../nette/forms/examples/live-validation.php | 106 + vendor/nette/forms/examples/localization.ini | 12 + vendor/nette/forms/examples/localization.php | 89 + .../nette/forms/examples/manual-rendering.php | 95 + vendor/nette/forms/license.md | 60 + vendor/nette/forms/package.json | 30 + vendor/nette/forms/readme.md | 93 + vendor/nette/forms/rollup.config.js | 78 + .../src/Bridges/FormsDI/FormsExtension.php | 44 + .../src/Bridges/FormsLatte/FormMacros.php | 330 + .../src/Bridges/FormsLatte/FormsExtension.php | 51 + .../FormsLatte/Nodes/FieldNNameNode.php | 128 + .../FormsLatte/Nodes/FormContainerNode.php | 60 + .../FormsLatte/Nodes/FormNNameNode.php | 85 + .../src/Bridges/FormsLatte/Nodes/FormNode.php | 93 + .../FormsLatte/Nodes/FormPrintNode.php | 60 + .../FormsLatte/Nodes/InputErrorNode.php | 51 + .../Bridges/FormsLatte/Nodes/InputNode.php | 71 + .../Bridges/FormsLatte/Nodes/LabelNode.php | 90 + .../forms/src/Bridges/FormsLatte/Runtime.php | 88 + vendor/nette/forms/src/Forms/Blueprint.php | 233 + vendor/nette/forms/src/Forms/Container.php | 608 + vendor/nette/forms/src/Forms/Control.php | 45 + vendor/nette/forms/src/Forms/ControlGroup.php | 123 + .../forms/src/Forms/Controls/BaseControl.php | 584 + .../nette/forms/src/Forms/Controls/Button.php | 75 + .../forms/src/Forms/Controls/Checkbox.php | 98 + .../forms/src/Forms/Controls/CheckboxList.php | 130 + .../src/Forms/Controls/ChoiceControl.php | 148 + .../forms/src/Forms/Controls/ColorPicker.php | 61 + .../src/Forms/Controls/CsrfProtection.php | 103 + .../src/Forms/Controls/DateTimeControl.php | 194 + .../forms/src/Forms/Controls/HiddenField.php | 114 + .../forms/src/Forms/Controls/ImageButton.php | 44 + .../src/Forms/Controls/MultiChoiceControl.php | 161 + .../src/Forms/Controls/MultiSelectBox.php | 96 + .../forms/src/Forms/Controls/RadioList.php | 126 + .../forms/src/Forms/Controls/SelectBox.php | 150 + .../forms/src/Forms/Controls/SubmitButton.php | 117 + .../forms/src/Forms/Controls/TextArea.php | 34 + .../forms/src/Forms/Controls/TextBase.php | 152 + .../forms/src/Forms/Controls/TextInput.php | 115 + .../src/Forms/Controls/UploadControl.php | 152 + vendor/nette/forms/src/Forms/Form.php | 796 ++ vendor/nette/forms/src/Forms/FormRenderer.php | 25 + vendor/nette/forms/src/Forms/Helpers.php | 324 + .../Forms/Rendering/DataClassGenerator.php | 33 + .../Forms/Rendering/DefaultFormRenderer.php | 529 + .../src/Forms/Rendering/LatteRenderer.php | 28 + vendor/nette/forms/src/Forms/Rule.php | 36 + vendor/nette/forms/src/Forms/Rules.php | 346 + .../forms/src/Forms/SubmitterControl.php | 25 + vendor/nette/forms/src/Forms/Validator.php | 410 + .../nette/forms/src/assets/formValidator.ts | 458 + vendor/nette/forms/src/assets/index.umd.ts | 10 + vendor/nette/forms/src/assets/netteForms.js | 563 + .../nette/forms/src/assets/netteForms.min.js | 7 + vendor/nette/forms/src/assets/package.json | 24 + vendor/nette/forms/src/assets/types.ts | 32 + vendor/nette/forms/src/assets/validators.ts | 192 + vendor/nette/forms/src/assets/webalize.ts | 16 + vendor/nette/forms/src/compatibility.php | 37 + vendor/nette/forms/tsconfig.json | 19 + vendor/nette/http/.phpstorm.meta.php | 79 + vendor/nette/http/composer.json | 54 + vendor/nette/http/license.md | 60 + vendor/nette/http/readme.md | 791 ++ .../http/src/Bridges/HttpDI/HttpExtension.php | 172 + .../src/Bridges/HttpDI/SessionExtension.php | 100 + .../src/Bridges/HttpTracy/SessionPanel.php | 41 + .../src/Bridges/HttpTracy/dist/panel.phtml | 32 + .../http/src/Bridges/HttpTracy/dist/tab.phtml | 9 + .../http/src/Bridges/HttpTracy/panel.latte | 32 + .../http/src/Bridges/HttpTracy/tab.latte | 5 + vendor/nette/http/src/Http/Context.php | 83 + vendor/nette/http/src/Http/FileUpload.php | 280 + vendor/nette/http/src/Http/Helpers.php | 63 + vendor/nette/http/src/Http/IRequest.php | 141 + vendor/nette/http/src/Http/IResponse.php | 411 + vendor/nette/http/src/Http/Request.php | 325 + vendor/nette/http/src/Http/RequestFactory.php | 384 + vendor/nette/http/src/Http/Response.php | 284 + vendor/nette/http/src/Http/Session.php | 562 + vendor/nette/http/src/Http/SessionSection.php | 230 + vendor/nette/http/src/Http/Url.php | 454 + vendor/nette/http/src/Http/UrlImmutable.php | 345 + vendor/nette/http/src/Http/UrlScript.php | 115 + vendor/nette/http/src/Http/UserStorage.php | 180 + vendor/nette/mail/.phpstorm.meta.php | 8 + vendor/nette/mail/composer.json | 48 + vendor/nette/mail/license.md | 60 + vendor/nette/mail/readme.md | 239 + .../mail/src/Bridges/MailDI/MailExtension.php | 88 + vendor/nette/mail/src/Mail/DkimSigner.php | 157 + vendor/nette/mail/src/Mail/FallbackMailer.php | 79 + vendor/nette/mail/src/Mail/Mailer.php | 32 + vendor/nette/mail/src/Mail/Message.php | 413 + vendor/nette/mail/src/Mail/MimePart.php | 327 + vendor/nette/mail/src/Mail/SendmailMailer.php | 81 + vendor/nette/mail/src/Mail/Signer.php | 20 + vendor/nette/mail/src/Mail/SmtpMailer.php | 241 + vendor/nette/mail/src/Mail/exceptions.php | 46 + vendor/nette/neon/bin/neon-lint | 154 + vendor/nette/neon/composer.json | 43 + vendor/nette/neon/license.md | 60 + vendor/nette/neon/readme.md | 521 + vendor/nette/neon/src/Neon/Decoder.php | 36 + vendor/nette/neon/src/Neon/Encoder.php | 105 + vendor/nette/neon/src/Neon/Entity.php | 31 + vendor/nette/neon/src/Neon/Exception.php | 18 + vendor/nette/neon/src/Neon/Lexer.php | 86 + vendor/nette/neon/src/Neon/Neon.php | 67 + vendor/nette/neon/src/Neon/Node.php | 35 + .../neon/src/Neon/Node/ArrayItemNode.php | 91 + vendor/nette/neon/src/Neon/Node/ArrayNode.php | 36 + .../neon/src/Neon/Node/BlockArrayNode.php | 33 + .../neon/src/Neon/Node/EntityChainNode.php | 51 + .../nette/neon/src/Neon/Node/EntityNode.php | 54 + .../neon/src/Neon/Node/InlineArrayNode.php | 28 + .../nette/neon/src/Neon/Node/LiteralNode.php | 117 + .../nette/neon/src/Neon/Node/StringNode.php | 98 + vendor/nette/neon/src/Neon/Parser.php | 266 + vendor/nette/neon/src/Neon/Token.php | 29 + vendor/nette/neon/src/Neon/TokenStream.php | 97 + vendor/nette/neon/src/Neon/Traverser.php | 78 + vendor/nette/php-generator/composer.json | 47 + vendor/nette/php-generator/license.md | 60 + vendor/nette/php-generator/readme.md | 1008 ++ .../src/PhpGenerator/Attribute.php | 49 + .../src/PhpGenerator/ClassLike.php | 148 + .../src/PhpGenerator/ClassManipulator.php | 124 + .../src/PhpGenerator/ClassType.php | 198 + .../src/PhpGenerator/Closure.php | 66 + .../src/PhpGenerator/Constant.php | 66 + .../php-generator/src/PhpGenerator/Dumper.php | 288 + .../src/PhpGenerator/EnumCase.php | 36 + .../src/PhpGenerator/EnumType.php | 148 + .../src/PhpGenerator/Extractor.php | 595 + .../src/PhpGenerator/Factory.php | 378 + .../src/PhpGenerator/GlobalFunction.php | 41 + .../src/PhpGenerator/Helpers.php | 156 + .../src/PhpGenerator/InterfaceType.php | 95 + .../src/PhpGenerator/Literal.php | 49 + .../php-generator/src/PhpGenerator/Method.php | 115 + .../src/PhpGenerator/Parameter.php | 96 + .../src/PhpGenerator/PhpFile.php | 193 + .../src/PhpGenerator/PhpLiteral.php | 16 + .../src/PhpGenerator/PhpNamespace.php | 412 + .../src/PhpGenerator/Printer.php | 543 + .../src/PhpGenerator/PromotedParameter.php | 35 + .../src/PhpGenerator/Property.php | 138 + .../src/PhpGenerator/PropertyAccessMode.php | 20 + .../src/PhpGenerator/PropertyHook.php | 129 + .../src/PhpGenerator/PropertyHookType.php | 20 + .../src/PhpGenerator/PsrPrinter.php | 27 + .../src/PhpGenerator/TraitType.php | 54 + .../src/PhpGenerator/TraitUse.php | 49 + .../PhpGenerator/Traits/AttributeAware.php | 49 + .../src/PhpGenerator/Traits/CommentAware.php | 49 + .../PhpGenerator/Traits/ConstantsAware.php | 79 + .../src/PhpGenerator/Traits/FunctionLike.php | 179 + .../src/PhpGenerator/Traits/MethodsAware.php | 89 + .../src/PhpGenerator/Traits/NameAware.php | 48 + .../PhpGenerator/Traits/PropertiesAware.php | 82 + .../src/PhpGenerator/Traits/PropertyLike.php | 160 + .../src/PhpGenerator/Traits/TraitsAware.php | 78 + .../PhpGenerator/Traits/VisibilityAware.php | 75 + .../php-generator/src/PhpGenerator/Type.php | 123 + .../src/PhpGenerator/Visibility.php | 21 + vendor/nette/robot-loader/composer.json | 43 + vendor/nette/robot-loader/license.md | 60 + vendor/nette/robot-loader/readme.md | 149 + .../src/RobotLoader/RobotLoader.php | 513 + vendor/nette/routing/.phpstorm.meta.php | 8 + vendor/nette/routing/composer.json | 43 + vendor/nette/routing/license.md | 60 + vendor/nette/routing/readme.md | 530 + vendor/nette/routing/src/Routing/Route.php | 638 + .../nette/routing/src/Routing/RouteList.php | 306 + vendor/nette/routing/src/Routing/Router.php | 32 + .../routing/src/Routing/SimpleRouter.php | 73 + vendor/nette/schema/composer.json | 42 + vendor/nette/schema/license.md | 60 + vendor/nette/schema/readme.md | 536 + vendor/nette/schema/src/Schema/Context.php | 53 + .../schema/src/Schema/DynamicParameter.php | 15 + .../schema/src/Schema/Elements/AnyOf.php | 148 + .../nette/schema/src/Schema/Elements/Base.php | 163 + .../schema/src/Schema/Elements/Structure.php | 211 + .../nette/schema/src/Schema/Elements/Type.php | 209 + vendor/nette/schema/src/Schema/Expect.php | 119 + vendor/nette/schema/src/Schema/Helpers.php | 184 + vendor/nette/schema/src/Schema/Message.php | 99 + vendor/nette/schema/src/Schema/Processor.php | 96 + vendor/nette/schema/src/Schema/Schema.php | 37 + .../schema/src/Schema/ValidationException.php | 55 + vendor/nette/security/composer.json | 49 + vendor/nette/security/license.md | 60 + vendor/nette/security/readme.md | 436 + .../Bridges/SecurityDI/SecurityExtension.php | 147 + .../Bridges/SecurityHttp/CookieStorage.php | 101 + .../Bridges/SecurityHttp/SessionStorage.php | 158 + .../src/Bridges/SecurityTracy/UserPanel.php | 63 + .../Bridges/SecurityTracy/dist/panel.phtml | 13 + .../src/Bridges/SecurityTracy/dist/tab.phtml | 10 + .../src/Bridges/SecurityTracy/panel.latte | 9 + .../src/Bridges/SecurityTracy/tab.latte | 7 + .../src/Security/AuthenticationException.php | 18 + .../security/src/Security/Authenticator.php | 42 + .../security/src/Security/Authorizator.php | 44 + .../security/src/Security/IAuthenticator.php | 37 + .../nette/security/src/Security/IIdentity.php | 34 + .../nette/security/src/Security/Identity.php | 118 + .../security/src/Security/IdentityHandler.php | 21 + .../nette/security/src/Security/Passwords.php | 73 + .../security/src/Security/Permission.php | 756 ++ .../nette/security/src/Security/Resource.php | 25 + vendor/nette/security/src/Security/Role.php | 25 + .../src/Security/SimpleAuthenticator.php | 61 + .../security/src/Security/SimpleIdentity.php | 18 + vendor/nette/security/src/Security/User.php | 332 + .../security/src/Security/UserStorage.php | 44 + vendor/nette/security/src/compatibility.php | 37 + vendor/nette/tester/composer.json | 42 + vendor/nette/tester/license.md | 49 + vendor/nette/tester/readme.md | 237 + .../tester/src/CodeCoverage/Collector.php | 199 + .../Generators/AbstractGenerator.php | 128 + .../Generators/CloverXMLGenerator.php | 227 + .../CodeCoverage/Generators/HtmlGenerator.php | 110 + .../CodeCoverage/Generators/template.phtml | 587 + .../tester/src/CodeCoverage/PhpParser.php | 190 + vendor/nette/tester/src/Framework/Assert.php | 692 + .../tester/src/Framework/AssertException.php | 42 + .../tester/src/Framework/DataProvider.php | 107 + .../nette/tester/src/Framework/DomQuery.php | 198 + vendor/nette/tester/src/Framework/Dumper.php | 435 + .../tester/src/Framework/Environment.php | 273 + vendor/nette/tester/src/Framework/Expect.php | 128 + .../nette/tester/src/Framework/FileMock.php | 220 + .../tester/src/Framework/FileMutator.php | 238 + vendor/nette/tester/src/Framework/Helpers.php | 155 + .../nette/tester/src/Framework/HttpAssert.php | 226 + .../nette/tester/src/Framework/TestCase.php | 296 + .../nette/tester/src/Framework/functions.php | 85 + vendor/nette/tester/src/Runner/CliTester.php | 396 + .../nette/tester/src/Runner/CommandLine.php | 192 + vendor/nette/tester/src/Runner/Job.php | 215 + .../src/Runner/Output/ConsolePrinter.php | 171 + .../tester/src/Runner/Output/JUnitPrinter.php | 76 + .../nette/tester/src/Runner/Output/Logger.php | 82 + .../tester/src/Runner/Output/TapPrinter.php | 65 + .../nette/tester/src/Runner/OutputHandler.php | 25 + .../tester/src/Runner/PhpInterpreter.php | 132 + vendor/nette/tester/src/Runner/Runner.php | 238 + vendor/nette/tester/src/Runner/Test.php | 154 + .../nette/tester/src/Runner/TestHandler.php | 309 + vendor/nette/tester/src/Runner/exceptions.php | 15 + vendor/nette/tester/src/Runner/info.php | 46 + vendor/nette/tester/src/bootstrap.php | 33 + vendor/nette/tester/src/tester | 6 + vendor/nette/tester/src/tester.php | 37 + vendor/nette/utils/.phpstorm.meta.php | 13 + vendor/nette/utils/composer.json | 54 + vendor/nette/utils/license.md | 60 + vendor/nette/utils/readme.md | 55 + vendor/nette/utils/src/HtmlStringable.php | 22 + .../utils/src/Iterators/CachingIterator.php | 150 + vendor/nette/utils/src/Iterators/Mapper.php | 33 + vendor/nette/utils/src/SmartObject.php | 140 + vendor/nette/utils/src/StaticClass.php | 24 + vendor/nette/utils/src/Translator.php | 25 + vendor/nette/utils/src/Utils/ArrayHash.php | 106 + vendor/nette/utils/src/Utils/ArrayList.php | 135 + vendor/nette/utils/src/Utils/Arrays.php | 551 + vendor/nette/utils/src/Utils/Callback.php | 137 + vendor/nette/utils/src/Utils/DateTime.php | 209 + vendor/nette/utils/src/Utils/FileInfo.php | 70 + vendor/nette/utils/src/Utils/FileSystem.php | 341 + vendor/nette/utils/src/Utils/Finder.php | 510 + vendor/nette/utils/src/Utils/Floats.php | 108 + vendor/nette/utils/src/Utils/Helpers.php | 121 + vendor/nette/utils/src/Utils/Html.php | 837 ++ vendor/nette/utils/src/Utils/Image.php | 818 ++ vendor/nette/utils/src/Utils/ImageColor.php | 76 + vendor/nette/utils/src/Utils/ImageType.php | 27 + vendor/nette/utils/src/Utils/Iterables.php | 265 + vendor/nette/utils/src/Utils/Json.php | 86 + .../nette/utils/src/Utils/ObjectHelpers.php | 231 + vendor/nette/utils/src/Utils/Paginator.php | 245 + vendor/nette/utils/src/Utils/Random.php | 54 + vendor/nette/utils/src/Utils/Reflection.php | 319 + .../utils/src/Utils/ReflectionMethod.php | 38 + vendor/nette/utils/src/Utils/Strings.php | 699 + vendor/nette/utils/src/Utils/Type.php | 302 + vendor/nette/utils/src/Utils/Validators.php | 417 + vendor/nette/utils/src/Utils/exceptions.php | 50 + vendor/nette/utils/src/compatibility.php | 32 + vendor/nette/utils/src/exceptions.php | 114 + .../constant_time_encoding/LICENSE.txt | 48 + .../constant_time_encoding/README.md | 88 + .../constant_time_encoding/composer.json | 67 + .../constant_time_encoding/src/Base32.php | 558 + .../constant_time_encoding/src/Base32Hex.php | 118 + .../constant_time_encoding/src/Base64.php | 381 + .../src/Base64DotSlash.php | 92 + .../src/Base64DotSlashOrdered.php | 86 + .../src/Base64UrlSafe.php | 99 + .../constant_time_encoding/src/Binary.php | 87 + .../src/EncoderInterface.php | 61 + .../constant_time_encoding/src/Encoding.php | 301 + .../constant_time_encoding/src/Hex.php | 176 + .../constant_time_encoding/src/RFC4648.php | 208 + vendor/phpstan/phpstan-nette/.editorconfig | 27 + vendor/phpstan/phpstan-nette/LICENSE | 22 + vendor/phpstan/phpstan-nette/README.md | 55 + vendor/phpstan/phpstan-nette/composer.json | 54 + vendor/phpstan/phpstan-nette/extension.neon | 134 + vendor/phpstan/phpstan-nette/rules.neon | 27 + .../Nette/HtmlClassReflectionExtension.php | 34 + .../Reflection/Nette/HtmlMethodReflection.php | 108 + .../Nette/HtmlPropertyReflection.php | 89 + .../NetteObjectClassReflectionExtension.php | 111 + ...tteObjectEventListenerMethodReflection.php | 105 + .../Nette/NetteObjectPropertyReflection.php | 88 + .../Rule/Nette/DoNotExtendNetteObjectRule.php | 45 + .../PresenterInjectedPropertiesExtension.php | 28 + .../Nette/RegularExpressionPatternRule.php | 109 + .../src/Rule/Nette/RethrowExceptionRule.php | 135 + .../Application/StubFilesExtensionLoader.php | 38 + ...GetPresenterDynamicReturnTypeExtension.php | 58 + ...ponentLookupDynamicReturnTypeExtension.php | 51 + ...lArrayAccessDynamicReturnTypeExtension.php | 79 + ...mponentModelDynamicReturnTypeExtension.php | 90 + ...UnsafeValuesDynamicReturnTypeExtension.php | 48 + ...tainerValuesDynamicReturnTypeExtension.php | 65 + ...sBaseControlDynamicReturnTypeExtension.php | 50 + ...PresenterGetSessionReturnTypeExtension.php | 35 + ...rviceLocatorDynamicReturnTypeExtension.php | 71 + ...ingsMatchAllDynamicReturnTypeExtension.php | 89 + ...StringsMatchDynamicReturnTypeExtension.php | 90 + ...ngsReplaceCallbackClosureTypeExtension.php | 140 + .../stubs/Application/Routers/RouteList.stub | 18 + .../stubs/Application/UI/Component.stub | 13 + .../stubs/Application/UI/Multiplier.stub | 19 + .../Application/UI/NullableMultiplier.stub | 19 + .../stubs/Application/UI/Presenter.stub | 8 + .../phpstan-nette/stubs/Caching/Cache.stub | 40 + .../stubs/ComponentModel/Component.stub | 8 + .../stubs/ComponentModel/Container.stub | 17 + .../stubs/ComponentModel/IComponent.stub | 8 + .../stubs/ComponentModel/IContainer.stub | 8 + .../stubs/Database/ResultSet.stub | 28 + .../stubs/Database/Table/ActiveRow.stub | 19 + .../stubs/Database/Table/Selection.stub | 47 + .../phpstan-nette/stubs/Forms/Container.stub | 19 + .../phpstan-nette/stubs/Forms/Form.stub | 20 + .../phpstan-nette/stubs/Forms/Rules.stub | 24 + .../phpstan-nette/stubs/Http/FileUpload.stub | 16 + .../stubs/Http/SessionSection.stub | 20 + .../phpstan-nette/stubs/Routing/Router.stub | 8 + .../phpstan-nette/stubs/Utils/ArrayHash.stub | 20 + .../phpstan-nette/stubs/Utils/Arrays.stub | 43 + .../phpstan-nette/stubs/Utils/Callback.stub | 24 + .../phpstan-nette/stubs/Utils/Helpers.stub | 15 + .../phpstan-nette/stubs/Utils/Html.stub | 20 + .../phpstan-nette/stubs/Utils/Paginator.stub | 23 + .../phpstan-nette/stubs/Utils/Random.stub | 16 + vendor/phpstan/phpstan/LICENSE | 22 + vendor/phpstan/phpstan/README.md | 121 + vendor/phpstan/phpstan/UPGRADING.md | 338 + vendor/phpstan/phpstan/bootstrap.php | 144 + vendor/phpstan/phpstan/composer.json | 31 + vendor/phpstan/phpstan/conf/bleedingEdge.neon | 2 + vendor/phpstan/phpstan/phpstan | 8 + vendor/phpstan/phpstan/phpstan.phar | Bin 0 -> 26247011 bytes vendor/phpstan/phpstan/phpstan.phar.asc | 16 + vendor/psr/clock/CHANGELOG.md | 11 + vendor/psr/clock/LICENSE | 19 + vendor/psr/clock/README.md | 61 + vendor/psr/clock/composer.json | 21 + vendor/psr/clock/src/ClockInterface.php | 13 + vendor/spomky-labs/otphp/CODE_OF_CONDUCT.md | 46 + vendor/spomky-labs/otphp/LICENSE | 20 + vendor/spomky-labs/otphp/README.md | 43 + vendor/spomky-labs/otphp/RELEASES.md | 18 + vendor/spomky-labs/otphp/SECURITY.md | 74 + vendor/spomky-labs/otphp/composer.json | 47 + .../src/Exception/InvalidLabelException.php | 25 + .../Exception/InvalidParameterException.php | 25 + .../InvalidProvisioningUriException.php | 15 + .../src/Exception/OTPExceptionInterface.php | 16 + .../Exception/ParameterNotFoundException.php | 23 + .../src/Exception/SecretDecodingException.php | 14 + vendor/spomky-labs/otphp/src/Factory.php | 114 + .../otphp/src/FactoryInterface.php | 18 + vendor/spomky-labs/otphp/src/HOTP.php | 165 + .../spomky-labs/otphp/src/HOTPInterface.php | 41 + .../spomky-labs/otphp/src/InternalClock.php | 21 + vendor/spomky-labs/otphp/src/OTP.php | 484 + vendor/spomky-labs/otphp/src/OTPInterface.php | 177 + vendor/spomky-labs/otphp/src/TOTP.php | 262 + .../spomky-labs/otphp/src/TOTPInterface.php | 61 + vendor/spomky-labs/otphp/src/Url.php | 104 + .../deprecation-contracts/CHANGELOG.md | 5 + vendor/symfony/deprecation-contracts/LICENSE | 19 + .../symfony/deprecation-contracts/README.md | 26 + .../deprecation-contracts/composer.json | 35 + .../deprecation-contracts/function.php | 27 + vendor/symfony/thanks/LICENSE | 19 + vendor/symfony/thanks/README.md | 53 + vendor/symfony/thanks/composer.json | 27 + .../thanks/src/Command/FundCommand.php | 92 + .../thanks/src/Command/ThanksCommand.php | 95 + vendor/symfony/thanks/src/GitHubClient.php | 249 + vendor/symfony/thanks/src/Thanks.php | 133 + vendor/tracy/tracy/.phpstorm.meta.php | 10 + vendor/tracy/tracy/composer.json | 52 + vendor/tracy/tracy/eslint.config.js | 19 + vendor/tracy/tracy/examples/ajax-fetch.php | 79 + vendor/tracy/tracy/examples/ajax-jquery.php | 79 + .../tracy/examples/assets/E_COMPILE_ERROR.php | 5 + vendor/tracy/tracy/examples/assets/arrow.png | Bin 0 -> 817 bytes vendor/tracy/tracy/examples/assets/style.css | 33 + vendor/tracy/tracy/examples/barDump.php | 32 + vendor/tracy/tracy/examples/dump-snapshot.php | 56 + vendor/tracy/tracy/examples/dump.php | 100 + vendor/tracy/tracy/examples/exception.php | 52 + vendor/tracy/tracy/examples/fatal-error.php | 24 + vendor/tracy/tracy/examples/notice.php | 33 + .../tracy/tracy/examples/output-debugger.php | 17 + vendor/tracy/tracy/examples/preloading.php | 34 + vendor/tracy/tracy/examples/redirect.php | 33 + vendor/tracy/tracy/examples/warning.php | 26 + vendor/tracy/tracy/license.md | 55 + vendor/tracy/tracy/package.json | 11 + vendor/tracy/tracy/readme.md | 461 + .../tracy/tracy/src/Bridges/Nette/Bridge.php | 92 + .../tracy/src/Bridges/Nette/MailSender.php | 57 + .../src/Bridges/Nette/TracyExtension.php | 185 + .../Bridges/Psr/PsrToTracyLoggerAdapter.php | 60 + .../Bridges/Psr/TracyToPsrLoggerAdapter.php | 58 + vendor/tracy/tracy/src/Tracy/Bar/Bar.php | 164 + .../tracy/src/Tracy/Bar/DefaultBarPanel.php | 55 + .../tracy/tracy/src/Tracy/Bar/IBarPanel.php | 29 + .../tracy/tracy/src/Tracy/Bar/assets/bar.css | 304 + .../tracy/tracy/src/Tracy/Bar/assets/bar.js | 681 + .../tracy/src/Tracy/Bar/assets/bar.phtml | 31 + .../tracy/src/Tracy/Bar/assets/loader.phtml | 29 + .../tracy/src/Tracy/Bar/assets/panels.phtml | 30 + .../src/Tracy/Bar/panels/dumps.panel.phtml | 29 + .../src/Tracy/Bar/panels/dumps.tab.phtml | 13 + .../src/Tracy/Bar/panels/info.panel.phtml | 125 + .../tracy/src/Tracy/Bar/panels/info.tab.phtml | 15 + .../src/Tracy/Bar/panels/warnings.panel.phtml | 20 + .../src/Tracy/Bar/panels/warnings.tab.phtml | 25 + .../tracy/src/Tracy/BlueScreen/BlueScreen.php | 513 + .../src/Tracy/BlueScreen/CodeHighlighter.php | 142 + .../Tracy/BlueScreen/assets/bluescreen.css | 422 + .../src/Tracy/BlueScreen/assets/bluescreen.js | 76 + .../src/Tracy/BlueScreen/assets/content.phtml | 73 + .../src/Tracy/BlueScreen/assets/page.phtml | 57 + .../Tracy/BlueScreen/assets/section-cli.phtml | 36 + .../assets/section-environment.phtml | 103 + .../assets/section-exception-causedBy.phtml | 29 + .../assets/section-exception-exception.phtml | 21 + .../BlueScreen/assets/section-exception.phtml | 72 + .../BlueScreen/assets/section-header.phtml | 35 + .../BlueScreen/assets/section-http.phtml | 124 + .../assets/section-lastMutedError.phtml | 29 + .../assets/section-stack-callStack.phtml | 92 + .../assets/section-stack-exception.phtml | 38 + .../assets/section-stack-fiber.phtml | 16 + .../assets/section-stack-generator.phtml | 21 + .../assets/section-stack-sourceFile.phtml | 46 + .../tracy/src/Tracy/Debugger/Debugger.php | 623 + .../src/Tracy/Debugger/DeferredContent.php | 158 + .../Tracy/Debugger/DevelopmentStrategy.php | 126 + .../src/Tracy/Debugger/ProductionStrategy.php | 86 + .../src/Tracy/Debugger/assets/error.500.phtml | 44 + .../tracy/src/Tracy/Dumper/Describer.php | 363 + .../tracy/tracy/src/Tracy/Dumper/Dumper.php | 262 + .../tracy/tracy/src/Tracy/Dumper/Exposer.php | 279 + .../tracy/tracy/src/Tracy/Dumper/Renderer.php | 426 + vendor/tracy/tracy/src/Tracy/Dumper/Value.php | 65 + .../src/Tracy/Dumper/assets/dumper-dark.css | 145 + .../src/Tracy/Dumper/assets/dumper-light.css | 145 + .../tracy/src/Tracy/Dumper/assets/dumper.js | 392 + vendor/tracy/tracy/src/Tracy/Helpers.php | 648 + .../tracy/tracy/src/Tracy/Logger/ILogger.php | 27 + .../tracy/tracy/src/Tracy/Logger/Logger.php | 198 + .../Tracy/OutputDebugger/OutputDebugger.php | 86 + .../tracy/src/Tracy/Session/FileSession.php | 108 + .../tracy/src/Tracy/Session/NativeSession.php | 28 + .../src/Tracy/Session/SessionStorage.php | 18 + .../tracy/tracy/src/Tracy/assets/helpers.js | 20 + vendor/tracy/tracy/src/Tracy/assets/reset.css | 386 + .../tracy/src/Tracy/assets/table-sort.css | 15 + .../tracy/src/Tracy/assets/table-sort.js | 39 + vendor/tracy/tracy/src/Tracy/assets/tabs.css | 11 + vendor/tracy/tracy/src/Tracy/assets/tabs.js | 40 + .../tracy/tracy/src/Tracy/assets/toggle.css | 35 + vendor/tracy/tracy/src/Tracy/assets/toggle.js | 116 + vendor/tracy/tracy/src/Tracy/functions.php | 46 + vendor/tracy/tracy/src/tracy.php | 31 + .../tracy/tools/create-phar/create-phar.php | 86 + .../tools/open-in-editor/linux/install.sh | 38 + .../tools/open-in-editor/linux/open-editor.sh | 109 + .../tools/open-in-editor/windows/install.cmd | 9 + .../open-in-editor/windows/open-editor.js | 84 + vite.config.ts | 18 + www/.htaccess | 41 + www/css/bootstrap.min.css | 11109 ++++++++++++++++ www/css/bootstrap.min.css.map | 1 + www/favicon.ico | Bin 0 -> 2550 bytes www/img/cas32x32.png | Bin 0 -> 2367 bytes www/img/exclamation1s.png | Bin 0 -> 755 bytes www/img/exclamation2s.png | Bin 0 -> 703 bytes www/img/exclamation3s.png | Bin 0 -> 705 bytes www/img/exclamation4s.png | Bin 0 -> 686 bytes www/img/exclamation5s.png | Bin 0 -> 686 bytes www/img/foto32x32.png | Bin 0 -> 541 bytes www/img/hodiny32x32.png | Bin 0 -> 2073 bytes www/img/kafe_in32x32.png | Bin 0 -> 1884 bytes www/img/kafe_out32x32.png | Bin 0 -> 2045 bytes www/img/kalendar16x16.png | Bin 0 -> 684 bytes www/img/kalendar32x32.png | Bin 0 -> 1504 bytes www/img/kontakty32x32.png | Bin 0 -> 473 bytes www/img/mapa32x32.png | Bin 0 -> 1574 bytes www/img/muz32x32.png | Bin 0 -> 1257 bytes www/img/navsteva32x32.png | Bin 0 -> 1184 bytes www/img/ok24x24.png | Bin 0 -> 882 bytes www/img/pneu32x32.png | Bin 0 -> 2590 bytes www/img/posledni32x32.png | Bin 0 -> 546 bytes www/img/poukaz32x32.png | Bin 0 -> 1827 bytes www/img/prachy32x32.png | Bin 0 -> 2512 bytes www/img/pracovnik16x16.png | Bin 0 -> 675 bytes www/img/pracovnik32x32.png | Bin 0 -> 1956 bytes www/img/qr16x16.png | Bin 0 -> 569 bytes www/img/sipka_in32x32.png | Bin 0 -> 1604 bytes www/img/sipka_out32x32.png | Bin 0 -> 1576 bytes www/img/tablety16x16.png | Bin 0 -> 777 bytes www/img/tablety32x32.png | Bin 0 -> 1965 bytes www/img/telefon24x24.png | Bin 0 -> 861 bytes www/img/telefon32x32.png | Bin 0 -> 417 bytes www/img/ukony32x32.png | Bin 0 -> 1051 bytes www/img/zajic.webp | Bin 0 -> 58446 bytes www/img/zaznamy32x32.png | Bin 0 -> 388 bytes www/img/zena32x32.png | Bin 0 -> 1350 bytes www/index.php | 10 + www/js/bootstrap.bundle.min.js | 7 + www/js/bootstrap.bundle.min.js.map | 1 + www/js/toast.js | 3 + www/robots.txt | 0 1191 files changed, 146980 insertions(+) create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 .vscode/sftp.json create mode 100644 app/Bootstrap.php create mode 100644 app/Core/AppPresenter.php create mode 100644 app/Core/Funkce.php create mode 100644 app/Core/MujAutentifikator.php create mode 100644 app/Core/MujAutorizator.php create mode 100644 app/Core/RouterFactory.php create mode 100644 app/Core/TwoFactorService.php create mode 100644 app/Model/FormData/CteckaFormData.php create mode 100644 app/Model/FormData/FotoFormData.php create mode 100644 app/Model/FormData/LoginFormData.php create mode 100644 app/Model/FormData/NavstevaFormData.php create mode 100644 app/Model/Login/ServerCredentials.php create mode 100644 app/Model/Login/UserIdentity.php create mode 100644 app/Model/UzivatelFacade.php create mode 100644 app/Presentation/@layout.latte create mode 100644 app/Presentation/Accessory/LatteExtension.php create mode 100644 app/Presentation/Disable2fa/Disable2faPresenter.php create mode 100644 app/Presentation/Disable2fa/default.latte create mode 100644 app/Presentation/Error/Error4xx/403.latte create mode 100644 app/Presentation/Error/Error4xx/404.latte create mode 100644 app/Presentation/Error/Error4xx/410.latte create mode 100644 app/Presentation/Error/Error4xx/4xx.latte create mode 100644 app/Presentation/Error/Error4xx/Error4xxPresenter.php create mode 100644 app/Presentation/Error/Error5xx/500.phtml create mode 100644 app/Presentation/Error/Error5xx/503.phtml create mode 100644 app/Presentation/Error/Error5xx/Error5xxPresenter.php create mode 100644 app/Presentation/Home/HomePresenter.php create mode 100644 app/Presentation/Home/default.latte create mode 100644 app/Presentation/Setup2fa/Setup2faPresenter.php create mode 100644 app/Presentation/Setup2fa/default.latte create mode 100644 app/Presentation/Sign/SignPresenter.php create mode 100644 app/Presentation/Sign/in.latte create mode 100644 app/Presentation/Sign/twoFactor.latte create mode 100644 assets/main.js create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/common.neon create mode 100644 config/services.neon create mode 100644 latte-lint create mode 100644 package.json create mode 100644 readme.md create mode 100644 vendor/autoload.php create mode 100644 vendor/bacon/bacon-qr-code/LICENSE create mode 100644 vendor/bacon/bacon-qr-code/README.md create mode 100644 vendor/bacon/bacon-qr-code/composer.json create mode 100644 vendor/bacon/bacon-qr-code/src/Common/BitArray.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/BitUtils.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/EcBlock.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/Mode.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php create mode 100644 vendor/bacon/bacon-qr-code/src/Common/Version.php create mode 100644 vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php create mode 100644 vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php create mode 100644 vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php create mode 100644 vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php create mode 100644 vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php create mode 100644 vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php create mode 100644 vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Exception/InvalidArgumentException.php create mode 100644 vendor/bacon/bacon-qr-code/src/Exception/OutOfBoundsException.php create mode 100644 vendor/bacon/bacon-qr-code/src/Exception/RuntimeException.php create mode 100644 vendor/bacon/bacon-qr-code/src/Exception/UnexpectedValueException.php create mode 100644 vendor/bacon/bacon-qr-code/src/Exception/WriterException.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Color/Alpha.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Color/Gray.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Eye/ModuleEye.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Eye/PointyEye.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/GDLibRenderer.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Image/ImagickImageBackEnd.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Module/RoundnessModule.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/Curve.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/Path/Path.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/EyeFill.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php create mode 100644 vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/RendererStyle.php create mode 100644 vendor/bacon/bacon-qr-code/src/Writer.php create mode 100644 vendor/bin/latte-lint create mode 100644 vendor/bin/latte-lint.bat create mode 100644 vendor/bin/neon-lint create mode 100644 vendor/bin/neon-lint.bat create mode 100644 vendor/bin/phpstan create mode 100644 vendor/bin/phpstan.bat create mode 100644 vendor/bin/phpstan.phar create mode 100644 vendor/bin/phpstan.phar.bat create mode 100644 vendor/bin/tester create mode 100644 vendor/bin/tester.bat create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/InstalledVersions.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/composer/installed.php create mode 100644 vendor/composer/platform_check.php create mode 100644 vendor/dasprid/enum/LICENSE create mode 100644 vendor/dasprid/enum/README.md create mode 100644 vendor/dasprid/enum/composer.json create mode 100644 vendor/dasprid/enum/src/AbstractEnum.php create mode 100644 vendor/dasprid/enum/src/EnumMap.php create mode 100644 vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php create mode 100644 vendor/dasprid/enum/src/Exception/ExceptionInterface.php create mode 100644 vendor/dasprid/enum/src/Exception/ExpectationException.php create mode 100644 vendor/dasprid/enum/src/Exception/IllegalArgumentException.php create mode 100644 vendor/dasprid/enum/src/Exception/MismatchException.php create mode 100644 vendor/dasprid/enum/src/Exception/SerializeNotSupportedException.php create mode 100644 vendor/dasprid/enum/src/Exception/UnserializeNotSupportedException.php create mode 100644 vendor/dasprid/enum/src/NullValue.php create mode 100644 vendor/endroid/qr-code/LICENSE create mode 100644 vendor/endroid/qr-code/README.md create mode 100644 vendor/endroid/qr-code/assets/open_sans.ttf create mode 100644 vendor/endroid/qr-code/composer.json create mode 100644 vendor/endroid/qr-code/src/Bacon/ErrorCorrectionLevelConverter.php create mode 100644 vendor/endroid/qr-code/src/Bacon/MatrixFactory.php create mode 100644 vendor/endroid/qr-code/src/Builder/Builder.php create mode 100644 vendor/endroid/qr-code/src/Builder/BuilderInterface.php create mode 100644 vendor/endroid/qr-code/src/Builder/BuilderRegistry.php create mode 100644 vendor/endroid/qr-code/src/Builder/BuilderRegistryInterface.php create mode 100644 vendor/endroid/qr-code/src/Color/Color.php create mode 100644 vendor/endroid/qr-code/src/Color/ColorInterface.php create mode 100644 vendor/endroid/qr-code/src/Encoding/Encoding.php create mode 100644 vendor/endroid/qr-code/src/Encoding/EncodingInterface.php create mode 100644 vendor/endroid/qr-code/src/ErrorCorrectionLevel.php create mode 100644 vendor/endroid/qr-code/src/Exception/BlockSizeTooSmallException.php create mode 100644 vendor/endroid/qr-code/src/Exception/ValidationException.php create mode 100644 vendor/endroid/qr-code/src/ImageData/LabelImageData.php create mode 100644 vendor/endroid/qr-code/src/ImageData/LogoImageData.php create mode 100644 vendor/endroid/qr-code/src/Label/Font/Font.php create mode 100644 vendor/endroid/qr-code/src/Label/Font/FontInterface.php create mode 100644 vendor/endroid/qr-code/src/Label/Font/OpenSans.php create mode 100644 vendor/endroid/qr-code/src/Label/Label.php create mode 100644 vendor/endroid/qr-code/src/Label/LabelAlignment.php create mode 100644 vendor/endroid/qr-code/src/Label/LabelInterface.php create mode 100644 vendor/endroid/qr-code/src/Label/Margin/Margin.php create mode 100644 vendor/endroid/qr-code/src/Label/Margin/MarginInterface.php create mode 100644 vendor/endroid/qr-code/src/Logo/Logo.php create mode 100644 vendor/endroid/qr-code/src/Logo/LogoInterface.php create mode 100644 vendor/endroid/qr-code/src/Matrix/Matrix.php create mode 100644 vendor/endroid/qr-code/src/Matrix/MatrixFactoryInterface.php create mode 100644 vendor/endroid/qr-code/src/Matrix/MatrixInterface.php create mode 100644 vendor/endroid/qr-code/src/QrCode.php create mode 100644 vendor/endroid/qr-code/src/QrCodeInterface.php create mode 100644 vendor/endroid/qr-code/src/RoundBlockSizeMode.php create mode 100644 vendor/endroid/qr-code/src/Writer/AbstractGdWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/BinaryWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/ConsoleWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/DebugWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/EpsWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/GifWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/PdfWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/PngWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/DebugResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/EpsResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/GdResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/GifResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/PdfResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/PngResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/SvgResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/Result/WebPResult.php create mode 100644 vendor/endroid/qr-code/src/Writer/SvgWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/ValidatingWriterInterface.php create mode 100644 vendor/endroid/qr-code/src/Writer/WebPWriter.php create mode 100644 vendor/endroid/qr-code/src/Writer/WriterInterface.php create mode 100644 vendor/latte/latte/bin/latte-lint create mode 100644 vendor/latte/latte/composer.json create mode 100644 vendor/latte/latte/license.md create mode 100644 vendor/latte/latte/readme.md create mode 100644 vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php create mode 100644 vendor/latte/latte/src/Bridges/Tracy/LattePanel.php create mode 100644 vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php create mode 100644 vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml create mode 100644 vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml create mode 100644 vendor/latte/latte/src/Bridges/Tracy/panel.latte create mode 100644 vendor/latte/latte/src/Bridges/Tracy/tab.latte create mode 100644 vendor/latte/latte/src/Latte/Cache.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Block.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Escaper.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Node.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/PrintNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Position.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/PrintContext.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Tag.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TagLexer.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TagParser.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TagParserData.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TemplateGenerator.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TemplateLexer.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TemplateParser.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TemplateParserHtml.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/Token.php create mode 100644 vendor/latte/latte/src/Latte/Compiler/TokenStream.php create mode 100644 vendor/latte/latte/src/Latte/ContentType.php create mode 100644 vendor/latte/latte/src/Latte/Engine.php create mode 100644 vendor/latte/latte/src/Latte/Essential/AuxiliaryIterator.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Blueprint.php create mode 100644 vendor/latte/latte/src/Latte/Essential/CachingIterator.php create mode 100644 vendor/latte/latte/src/Latte/Essential/CoreExtension.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Filters.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/TraceNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/TryNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/VarNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Nodes/WhileNode.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Passes.php create mode 100644 vendor/latte/latte/src/Latte/Essential/RawPhpExtension.php create mode 100644 vendor/latte/latte/src/Latte/Essential/RollbackException.php create mode 100644 vendor/latte/latte/src/Latte/Essential/Tracer.php create mode 100644 vendor/latte/latte/src/Latte/Essential/TranslatorExtension.php create mode 100644 vendor/latte/latte/src/Latte/Extension.php create mode 100644 vendor/latte/latte/src/Latte/Helpers.php create mode 100644 vendor/latte/latte/src/Latte/Loader.php create mode 100644 vendor/latte/latte/src/Latte/Loaders/FileLoader.php create mode 100644 vendor/latte/latte/src/Latte/Loaders/StringLoader.php create mode 100644 vendor/latte/latte/src/Latte/Policy.php create mode 100644 vendor/latte/latte/src/Latte/PositionAwareException.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/Block.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/FilterExecutor.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/FilterInfo.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/FunctionExecutor.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/Helpers.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/Html.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/HtmlHelpers.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/HtmlStringable.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/Template.php create mode 100644 vendor/latte/latte/src/Latte/Runtime/XmlHelpers.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/RuntimeChecker.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/SandboxExtension.php create mode 100644 vendor/latte/latte/src/Latte/Sandbox/SecurityPolicy.php create mode 100644 vendor/latte/latte/src/Latte/attributes.php create mode 100644 vendor/latte/latte/src/Latte/exceptions.php create mode 100644 vendor/latte/latte/src/Tools/Linter.php create mode 100644 vendor/latte/latte/src/Tools/LinterExtension.php create mode 100644 vendor/nette/application/.phpstorm.meta.php create mode 100644 vendor/nette/application/composer.json create mode 100644 vendor/nette/application/license.md create mode 100644 vendor/nette/application/readme.md create mode 100644 vendor/nette/application/src/Application/Application.php create mode 100644 vendor/nette/application/src/Application/Attributes/CrossOrigin.php create mode 100644 vendor/nette/application/src/Application/Attributes/Deprecated.php create mode 100644 vendor/nette/application/src/Application/Attributes/Parameter.php create mode 100644 vendor/nette/application/src/Application/Attributes/Persistent.php create mode 100644 vendor/nette/application/src/Application/Attributes/Requires.php create mode 100644 vendor/nette/application/src/Application/Attributes/TemplateVariable.php create mode 100644 vendor/nette/application/src/Application/ErrorPresenter.php create mode 100644 vendor/nette/application/src/Application/Helpers.php create mode 100644 vendor/nette/application/src/Application/IPresenter.php create mode 100644 vendor/nette/application/src/Application/IPresenterFactory.php create mode 100644 vendor/nette/application/src/Application/LinkGenerator.php create mode 100644 vendor/nette/application/src/Application/MicroPresenter.php create mode 100644 vendor/nette/application/src/Application/PresenterFactory.php create mode 100644 vendor/nette/application/src/Application/Request.php create mode 100644 vendor/nette/application/src/Application/Response.php create mode 100644 vendor/nette/application/src/Application/Responses/CallbackResponse.php create mode 100644 vendor/nette/application/src/Application/Responses/FileResponse.php create mode 100644 vendor/nette/application/src/Application/Responses/ForwardResponse.php create mode 100644 vendor/nette/application/src/Application/Responses/JsonResponse.php create mode 100644 vendor/nette/application/src/Application/Responses/RedirectResponse.php create mode 100644 vendor/nette/application/src/Application/Responses/TextResponse.php create mode 100644 vendor/nette/application/src/Application/Responses/VoidResponse.php create mode 100644 vendor/nette/application/src/Application/Routers/CliRouter.php create mode 100644 vendor/nette/application/src/Application/Routers/Route.php create mode 100644 vendor/nette/application/src/Application/Routers/RouteList.php create mode 100644 vendor/nette/application/src/Application/Routers/SimpleRouter.php create mode 100644 vendor/nette/application/src/Application/UI/AccessPolicy.php create mode 100644 vendor/nette/application/src/Application/UI/BadSignalException.php create mode 100644 vendor/nette/application/src/Application/UI/Component.php create mode 100644 vendor/nette/application/src/Application/UI/ComponentReflection.php create mode 100644 vendor/nette/application/src/Application/UI/Control.php create mode 100644 vendor/nette/application/src/Application/UI/Form.php create mode 100644 vendor/nette/application/src/Application/UI/InvalidLinkException.php create mode 100644 vendor/nette/application/src/Application/UI/Link.php create mode 100644 vendor/nette/application/src/Application/UI/MethodReflection.php create mode 100644 vendor/nette/application/src/Application/UI/Multiplier.php create mode 100644 vendor/nette/application/src/Application/UI/ParameterConverter.php create mode 100644 vendor/nette/application/src/Application/UI/Presenter.php create mode 100644 vendor/nette/application/src/Application/UI/Renderable.php create mode 100644 vendor/nette/application/src/Application/UI/SignalReceiver.php create mode 100644 vendor/nette/application/src/Application/UI/StatePersistent.php create mode 100644 vendor/nette/application/src/Application/UI/Template.php create mode 100644 vendor/nette/application/src/Application/UI/TemplateFactory.php create mode 100644 vendor/nette/application/src/Application/exceptions.php create mode 100644 vendor/nette/application/src/Application/templates/error.phtml create mode 100644 vendor/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/ControlNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/Template.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/UIMacros.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php create mode 100644 vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml create mode 100644 vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml create mode 100644 vendor/nette/application/src/Bridges/ApplicationTracy/panel.latte create mode 100644 vendor/nette/application/src/Bridges/ApplicationTracy/tab.latte create mode 100644 vendor/nette/application/src/compatibility-intf.php create mode 100644 vendor/nette/application/src/compatibility.php create mode 100644 vendor/nette/assets/composer.json create mode 100644 vendor/nette/assets/license.md create mode 100644 vendor/nette/assets/readme.md create mode 100644 vendor/nette/assets/src/Assets/Asset.php create mode 100644 vendor/nette/assets/src/Assets/AudioAsset.php create mode 100644 vendor/nette/assets/src/Assets/EntryAsset.php create mode 100644 vendor/nette/assets/src/Assets/FilesystemMapper.php create mode 100644 vendor/nette/assets/src/Assets/FontAsset.php create mode 100644 vendor/nette/assets/src/Assets/GenericAsset.php create mode 100644 vendor/nette/assets/src/Assets/Helpers.php create mode 100644 vendor/nette/assets/src/Assets/HtmlRenderable.php create mode 100644 vendor/nette/assets/src/Assets/ImageAsset.php create mode 100644 vendor/nette/assets/src/Assets/LazyLoad.php create mode 100644 vendor/nette/assets/src/Assets/Mapper.php create mode 100644 vendor/nette/assets/src/Assets/Registry.php create mode 100644 vendor/nette/assets/src/Assets/ScriptAsset.php create mode 100644 vendor/nette/assets/src/Assets/StyleAsset.php create mode 100644 vendor/nette/assets/src/Assets/VideoAsset.php create mode 100644 vendor/nette/assets/src/Assets/ViteMapper.php create mode 100644 vendor/nette/assets/src/Assets/exceptions.php create mode 100644 vendor/nette/assets/src/Bridges/AssetsDI/DIExtension.php create mode 100644 vendor/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php create mode 100644 vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php create mode 100644 vendor/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php create mode 100644 vendor/nette/assets/src/Bridges/AssetsLatte/Runtime.php create mode 100644 vendor/nette/bootstrap/composer.json create mode 100644 vendor/nette/bootstrap/config.stub.neon create mode 100644 vendor/nette/bootstrap/license.md create mode 100644 vendor/nette/bootstrap/readme.md create mode 100644 vendor/nette/bootstrap/src/Bootstrap/Configurator.php create mode 100644 vendor/nette/bootstrap/src/Bootstrap/Extensions/ConstantsExtension.php create mode 100644 vendor/nette/bootstrap/src/Bootstrap/Extensions/PhpExtension.php create mode 100644 vendor/nette/bootstrap/src/Configurator.php create mode 100644 vendor/nette/caching/composer.json create mode 100644 vendor/nette/caching/license.md create mode 100644 vendor/nette/caching/readme.md create mode 100644 vendor/nette/caching/src/Bridges/CacheDI/CacheExtension.php create mode 100644 vendor/nette/caching/src/Bridges/CacheLatte/CacheExtension.php create mode 100644 vendor/nette/caching/src/Bridges/CacheLatte/Nodes/CacheNode.php create mode 100644 vendor/nette/caching/src/Bridges/CacheLatte/Runtime.php create mode 100644 vendor/nette/caching/src/Bridges/Psr/PsrCacheAdapter.php create mode 100644 vendor/nette/caching/src/Caching/BulkReader.php create mode 100644 vendor/nette/caching/src/Caching/BulkWriter.php create mode 100644 vendor/nette/caching/src/Caching/Cache.php create mode 100644 vendor/nette/caching/src/Caching/OutputHelper.php create mode 100644 vendor/nette/caching/src/Caching/Storage.php create mode 100644 vendor/nette/caching/src/Caching/Storages/DevNullStorage.php create mode 100644 vendor/nette/caching/src/Caching/Storages/FileStorage.php create mode 100644 vendor/nette/caching/src/Caching/Storages/Journal.php create mode 100644 vendor/nette/caching/src/Caching/Storages/MemcachedStorage.php create mode 100644 vendor/nette/caching/src/Caching/Storages/MemoryStorage.php create mode 100644 vendor/nette/caching/src/Caching/Storages/SQLiteJournal.php create mode 100644 vendor/nette/caching/src/Caching/Storages/SQLiteStorage.php create mode 100644 vendor/nette/caching/src/compatibility.php create mode 100644 vendor/nette/component-model/.phpstorm.meta.php create mode 100644 vendor/nette/component-model/composer.json create mode 100644 vendor/nette/component-model/license.md create mode 100644 vendor/nette/component-model/readme.md create mode 100644 vendor/nette/component-model/src/ComponentModel/ArrayAccess.php create mode 100644 vendor/nette/component-model/src/ComponentModel/Component.php create mode 100644 vendor/nette/component-model/src/ComponentModel/Container.php create mode 100644 vendor/nette/component-model/src/ComponentModel/IComponent.php create mode 100644 vendor/nette/component-model/src/ComponentModel/IContainer.php create mode 100644 vendor/nette/component-model/src/ComponentModel/RecursiveComponentIterator.php create mode 100644 vendor/nette/database/composer.json create mode 100644 vendor/nette/database/license.md create mode 100644 vendor/nette/database/readme.md create mode 100644 vendor/nette/database/src/Bridges/DatabaseDI/DatabaseExtension.php create mode 100644 vendor/nette/database/src/Bridges/DatabaseTracy/ConnectionPanel.php create mode 100644 vendor/nette/database/src/Bridges/DatabaseTracy/dist/panel.phtml create mode 100644 vendor/nette/database/src/Bridges/DatabaseTracy/dist/tab.phtml create mode 100644 vendor/nette/database/src/Bridges/DatabaseTracy/panel.latte create mode 100644 vendor/nette/database/src/Bridges/DatabaseTracy/tab.latte create mode 100644 vendor/nette/database/src/Database/Connection.php create mode 100644 vendor/nette/database/src/Database/Conventions.php create mode 100644 vendor/nette/database/src/Database/Conventions/AmbiguousReferenceKeyException.php create mode 100644 vendor/nette/database/src/Database/Conventions/DiscoveredConventions.php create mode 100644 vendor/nette/database/src/Database/Conventions/StaticConventions.php create mode 100644 vendor/nette/database/src/Database/DateTime.php create mode 100644 vendor/nette/database/src/Database/Driver.php create mode 100644 vendor/nette/database/src/Database/DriverException.php create mode 100644 vendor/nette/database/src/Database/Drivers/MsSqlDriver.php create mode 100644 vendor/nette/database/src/Database/Drivers/MySqlDriver.php create mode 100644 vendor/nette/database/src/Database/Drivers/OciDriver.php create mode 100644 vendor/nette/database/src/Database/Drivers/OdbcDriver.php create mode 100644 vendor/nette/database/src/Database/Drivers/PgSqlDriver.php create mode 100644 vendor/nette/database/src/Database/Drivers/SqliteDriver.php create mode 100644 vendor/nette/database/src/Database/Drivers/SqlsrvDriver.php create mode 100644 vendor/nette/database/src/Database/Explorer.php create mode 100644 vendor/nette/database/src/Database/Helpers.php create mode 100644 vendor/nette/database/src/Database/IRow.php create mode 100644 vendor/nette/database/src/Database/IRowContainer.php create mode 100644 vendor/nette/database/src/Database/IStructure.php create mode 100644 vendor/nette/database/src/Database/Reflection.php create mode 100644 vendor/nette/database/src/Database/Reflection/Column.php create mode 100644 vendor/nette/database/src/Database/Reflection/ForeignKey.php create mode 100644 vendor/nette/database/src/Database/Reflection/Index.php create mode 100644 vendor/nette/database/src/Database/Reflection/Table.php create mode 100644 vendor/nette/database/src/Database/ResultSet.php create mode 100644 vendor/nette/database/src/Database/Row.php create mode 100644 vendor/nette/database/src/Database/SqlLiteral.php create mode 100644 vendor/nette/database/src/Database/SqlPreprocessor.php create mode 100644 vendor/nette/database/src/Database/Structure.php create mode 100644 vendor/nette/database/src/Database/Table/ActiveRow.php create mode 100644 vendor/nette/database/src/Database/Table/GroupedSelection.php create mode 100644 vendor/nette/database/src/Database/Table/IRow.php create mode 100644 vendor/nette/database/src/Database/Table/IRowContainer.php create mode 100644 vendor/nette/database/src/Database/Table/Selection.php create mode 100644 vendor/nette/database/src/Database/Table/SqlBuilder.php create mode 100644 vendor/nette/database/src/Database/exceptions.php create mode 100644 vendor/nette/database/src/compatibility-intf.php create mode 100644 vendor/nette/database/src/compatibility.php create mode 100644 vendor/nette/di/.phpstorm.meta.php create mode 100644 vendor/nette/di/composer.json create mode 100644 vendor/nette/di/license.md create mode 100644 vendor/nette/di/readme.md create mode 100644 vendor/nette/di/src/Bridges/DITracy/ContainerPanel.php create mode 100644 vendor/nette/di/src/Bridges/DITracy/dist/panel.phtml create mode 100644 vendor/nette/di/src/Bridges/DITracy/dist/tab.phtml create mode 100644 vendor/nette/di/src/Bridges/DITracy/panel.latte create mode 100644 vendor/nette/di/src/Bridges/DITracy/tab.latte create mode 100644 vendor/nette/di/src/DI/Attributes/Inject.php create mode 100644 vendor/nette/di/src/DI/Autowiring.php create mode 100644 vendor/nette/di/src/DI/Compiler.php create mode 100644 vendor/nette/di/src/DI/CompilerExtension.php create mode 100644 vendor/nette/di/src/DI/Config/Adapter.php create mode 100644 vendor/nette/di/src/DI/Config/Adapters/NeonAdapter.php create mode 100644 vendor/nette/di/src/DI/Config/Adapters/PhpAdapter.php create mode 100644 vendor/nette/di/src/DI/Config/Helpers.php create mode 100644 vendor/nette/di/src/DI/Config/Loader.php create mode 100644 vendor/nette/di/src/DI/Container.php create mode 100644 vendor/nette/di/src/DI/ContainerBuilder.php create mode 100644 vendor/nette/di/src/DI/ContainerLoader.php create mode 100644 vendor/nette/di/src/DI/Definitions/AccessorDefinition.php create mode 100644 vendor/nette/di/src/DI/Definitions/Definition.php create mode 100644 vendor/nette/di/src/DI/Definitions/FactoryDefinition.php create mode 100644 vendor/nette/di/src/DI/Definitions/ImportedDefinition.php create mode 100644 vendor/nette/di/src/DI/Definitions/LocatorDefinition.php create mode 100644 vendor/nette/di/src/DI/Definitions/Reference.php create mode 100644 vendor/nette/di/src/DI/Definitions/ServiceDefinition.php create mode 100644 vendor/nette/di/src/DI/Definitions/Statement.php create mode 100644 vendor/nette/di/src/DI/DependencyChecker.php create mode 100644 vendor/nette/di/src/DI/DynamicParameter.php create mode 100644 vendor/nette/di/src/DI/Extensions/DIExtension.php create mode 100644 vendor/nette/di/src/DI/Extensions/DecoratorExtension.php create mode 100644 vendor/nette/di/src/DI/Extensions/DefinitionSchema.php create mode 100644 vendor/nette/di/src/DI/Extensions/ExtensionsExtension.php create mode 100644 vendor/nette/di/src/DI/Extensions/InjectExtension.php create mode 100644 vendor/nette/di/src/DI/Extensions/ParametersExtension.php create mode 100644 vendor/nette/di/src/DI/Extensions/SearchExtension.php create mode 100644 vendor/nette/di/src/DI/Extensions/ServicesExtension.php create mode 100644 vendor/nette/di/src/DI/Helpers.php create mode 100644 vendor/nette/di/src/DI/PhpGenerator.php create mode 100644 vendor/nette/di/src/DI/Resolver.php create mode 100644 vendor/nette/di/src/DI/exceptions.php create mode 100644 vendor/nette/di/src/compatibility.php create mode 100644 vendor/nette/forms/.phpstorm.meta.php create mode 100644 vendor/nette/forms/composer.json create mode 100644 vendor/nette/forms/eslint.config.js create mode 100644 vendor/nette/forms/examples/assets/logo.png create mode 100644 vendor/nette/forms/examples/assets/style.css create mode 100644 vendor/nette/forms/examples/basic-example.php create mode 100644 vendor/nette/forms/examples/bootstrap4-rendering.php create mode 100644 vendor/nette/forms/examples/bootstrap5-rendering.php create mode 100644 vendor/nette/forms/examples/containers.php create mode 100644 vendor/nette/forms/examples/custom-control.php create mode 100644 vendor/nette/forms/examples/custom-rendering.php create mode 100644 vendor/nette/forms/examples/custom-validator.php create mode 100644 vendor/nette/forms/examples/html5.php create mode 100644 vendor/nette/forms/examples/latte.php create mode 100644 vendor/nette/forms/examples/latte/form-bootstrap5.latte create mode 100644 vendor/nette/forms/examples/latte/form.latte create mode 100644 vendor/nette/forms/examples/latte/page.latte create mode 100644 vendor/nette/forms/examples/live-validation.php create mode 100644 vendor/nette/forms/examples/localization.ini create mode 100644 vendor/nette/forms/examples/localization.php create mode 100644 vendor/nette/forms/examples/manual-rendering.php create mode 100644 vendor/nette/forms/license.md create mode 100644 vendor/nette/forms/package.json create mode 100644 vendor/nette/forms/readme.md create mode 100644 vendor/nette/forms/rollup.config.js create mode 100644 vendor/nette/forms/src/Bridges/FormsDI/FormsExtension.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/FormMacros.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/FormsExtension.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FormContainerNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FormNNameNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FormNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/FormPrintNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/InputErrorNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/InputNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Nodes/LabelNode.php create mode 100644 vendor/nette/forms/src/Bridges/FormsLatte/Runtime.php create mode 100644 vendor/nette/forms/src/Forms/Blueprint.php create mode 100644 vendor/nette/forms/src/Forms/Container.php create mode 100644 vendor/nette/forms/src/Forms/Control.php create mode 100644 vendor/nette/forms/src/Forms/ControlGroup.php create mode 100644 vendor/nette/forms/src/Forms/Controls/BaseControl.php create mode 100644 vendor/nette/forms/src/Forms/Controls/Button.php create mode 100644 vendor/nette/forms/src/Forms/Controls/Checkbox.php create mode 100644 vendor/nette/forms/src/Forms/Controls/CheckboxList.php create mode 100644 vendor/nette/forms/src/Forms/Controls/ChoiceControl.php create mode 100644 vendor/nette/forms/src/Forms/Controls/ColorPicker.php create mode 100644 vendor/nette/forms/src/Forms/Controls/CsrfProtection.php create mode 100644 vendor/nette/forms/src/Forms/Controls/DateTimeControl.php create mode 100644 vendor/nette/forms/src/Forms/Controls/HiddenField.php create mode 100644 vendor/nette/forms/src/Forms/Controls/ImageButton.php create mode 100644 vendor/nette/forms/src/Forms/Controls/MultiChoiceControl.php create mode 100644 vendor/nette/forms/src/Forms/Controls/MultiSelectBox.php create mode 100644 vendor/nette/forms/src/Forms/Controls/RadioList.php create mode 100644 vendor/nette/forms/src/Forms/Controls/SelectBox.php create mode 100644 vendor/nette/forms/src/Forms/Controls/SubmitButton.php create mode 100644 vendor/nette/forms/src/Forms/Controls/TextArea.php create mode 100644 vendor/nette/forms/src/Forms/Controls/TextBase.php create mode 100644 vendor/nette/forms/src/Forms/Controls/TextInput.php create mode 100644 vendor/nette/forms/src/Forms/Controls/UploadControl.php create mode 100644 vendor/nette/forms/src/Forms/Form.php create mode 100644 vendor/nette/forms/src/Forms/FormRenderer.php create mode 100644 vendor/nette/forms/src/Forms/Helpers.php create mode 100644 vendor/nette/forms/src/Forms/Rendering/DataClassGenerator.php create mode 100644 vendor/nette/forms/src/Forms/Rendering/DefaultFormRenderer.php create mode 100644 vendor/nette/forms/src/Forms/Rendering/LatteRenderer.php create mode 100644 vendor/nette/forms/src/Forms/Rule.php create mode 100644 vendor/nette/forms/src/Forms/Rules.php create mode 100644 vendor/nette/forms/src/Forms/SubmitterControl.php create mode 100644 vendor/nette/forms/src/Forms/Validator.php create mode 100644 vendor/nette/forms/src/assets/formValidator.ts create mode 100644 vendor/nette/forms/src/assets/index.umd.ts create mode 100644 vendor/nette/forms/src/assets/netteForms.js create mode 100644 vendor/nette/forms/src/assets/netteForms.min.js create mode 100644 vendor/nette/forms/src/assets/package.json create mode 100644 vendor/nette/forms/src/assets/types.ts create mode 100644 vendor/nette/forms/src/assets/validators.ts create mode 100644 vendor/nette/forms/src/assets/webalize.ts create mode 100644 vendor/nette/forms/src/compatibility.php create mode 100644 vendor/nette/forms/tsconfig.json create mode 100644 vendor/nette/http/.phpstorm.meta.php create mode 100644 vendor/nette/http/composer.json create mode 100644 vendor/nette/http/license.md create mode 100644 vendor/nette/http/readme.md create mode 100644 vendor/nette/http/src/Bridges/HttpDI/HttpExtension.php create mode 100644 vendor/nette/http/src/Bridges/HttpDI/SessionExtension.php create mode 100644 vendor/nette/http/src/Bridges/HttpTracy/SessionPanel.php create mode 100644 vendor/nette/http/src/Bridges/HttpTracy/dist/panel.phtml create mode 100644 vendor/nette/http/src/Bridges/HttpTracy/dist/tab.phtml create mode 100644 vendor/nette/http/src/Bridges/HttpTracy/panel.latte create mode 100644 vendor/nette/http/src/Bridges/HttpTracy/tab.latte create mode 100644 vendor/nette/http/src/Http/Context.php create mode 100644 vendor/nette/http/src/Http/FileUpload.php create mode 100644 vendor/nette/http/src/Http/Helpers.php create mode 100644 vendor/nette/http/src/Http/IRequest.php create mode 100644 vendor/nette/http/src/Http/IResponse.php create mode 100644 vendor/nette/http/src/Http/Request.php create mode 100644 vendor/nette/http/src/Http/RequestFactory.php create mode 100644 vendor/nette/http/src/Http/Response.php create mode 100644 vendor/nette/http/src/Http/Session.php create mode 100644 vendor/nette/http/src/Http/SessionSection.php create mode 100644 vendor/nette/http/src/Http/Url.php create mode 100644 vendor/nette/http/src/Http/UrlImmutable.php create mode 100644 vendor/nette/http/src/Http/UrlScript.php create mode 100644 vendor/nette/http/src/Http/UserStorage.php create mode 100644 vendor/nette/mail/.phpstorm.meta.php create mode 100644 vendor/nette/mail/composer.json create mode 100644 vendor/nette/mail/license.md create mode 100644 vendor/nette/mail/readme.md create mode 100644 vendor/nette/mail/src/Bridges/MailDI/MailExtension.php create mode 100644 vendor/nette/mail/src/Mail/DkimSigner.php create mode 100644 vendor/nette/mail/src/Mail/FallbackMailer.php create mode 100644 vendor/nette/mail/src/Mail/Mailer.php create mode 100644 vendor/nette/mail/src/Mail/Message.php create mode 100644 vendor/nette/mail/src/Mail/MimePart.php create mode 100644 vendor/nette/mail/src/Mail/SendmailMailer.php create mode 100644 vendor/nette/mail/src/Mail/Signer.php create mode 100644 vendor/nette/mail/src/Mail/SmtpMailer.php create mode 100644 vendor/nette/mail/src/Mail/exceptions.php create mode 100644 vendor/nette/neon/bin/neon-lint create mode 100644 vendor/nette/neon/composer.json create mode 100644 vendor/nette/neon/license.md create mode 100644 vendor/nette/neon/readme.md create mode 100644 vendor/nette/neon/src/Neon/Decoder.php create mode 100644 vendor/nette/neon/src/Neon/Encoder.php create mode 100644 vendor/nette/neon/src/Neon/Entity.php create mode 100644 vendor/nette/neon/src/Neon/Exception.php create mode 100644 vendor/nette/neon/src/Neon/Lexer.php create mode 100644 vendor/nette/neon/src/Neon/Neon.php create mode 100644 vendor/nette/neon/src/Neon/Node.php create mode 100644 vendor/nette/neon/src/Neon/Node/ArrayItemNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/ArrayNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/BlockArrayNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/EntityChainNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/EntityNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/InlineArrayNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/LiteralNode.php create mode 100644 vendor/nette/neon/src/Neon/Node/StringNode.php create mode 100644 vendor/nette/neon/src/Neon/Parser.php create mode 100644 vendor/nette/neon/src/Neon/Token.php create mode 100644 vendor/nette/neon/src/Neon/TokenStream.php create mode 100644 vendor/nette/neon/src/Neon/Traverser.php create mode 100644 vendor/nette/php-generator/composer.json create mode 100644 vendor/nette/php-generator/license.md create mode 100644 vendor/nette/php-generator/readme.md create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Attribute.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/ClassLike.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/ClassManipulator.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/ClassType.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Closure.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Constant.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Dumper.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/EnumCase.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/EnumType.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Extractor.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Factory.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/GlobalFunction.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Helpers.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/InterfaceType.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Literal.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Method.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Parameter.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PhpFile.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PhpLiteral.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PhpNamespace.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Printer.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PromotedParameter.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Property.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PropertyAccessMode.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PropertyHook.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PropertyHookType.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/PsrPrinter.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/TraitType.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/TraitUse.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/ConstantsAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/MethodsAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/NameAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/PropertiesAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/PropertyLike.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/TraitsAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Type.php create mode 100644 vendor/nette/php-generator/src/PhpGenerator/Visibility.php create mode 100644 vendor/nette/robot-loader/composer.json create mode 100644 vendor/nette/robot-loader/license.md create mode 100644 vendor/nette/robot-loader/readme.md create mode 100644 vendor/nette/robot-loader/src/RobotLoader/RobotLoader.php create mode 100644 vendor/nette/routing/.phpstorm.meta.php create mode 100644 vendor/nette/routing/composer.json create mode 100644 vendor/nette/routing/license.md create mode 100644 vendor/nette/routing/readme.md create mode 100644 vendor/nette/routing/src/Routing/Route.php create mode 100644 vendor/nette/routing/src/Routing/RouteList.php create mode 100644 vendor/nette/routing/src/Routing/Router.php create mode 100644 vendor/nette/routing/src/Routing/SimpleRouter.php create mode 100644 vendor/nette/schema/composer.json create mode 100644 vendor/nette/schema/license.md create mode 100644 vendor/nette/schema/readme.md create mode 100644 vendor/nette/schema/src/Schema/Context.php create mode 100644 vendor/nette/schema/src/Schema/DynamicParameter.php create mode 100644 vendor/nette/schema/src/Schema/Elements/AnyOf.php create mode 100644 vendor/nette/schema/src/Schema/Elements/Base.php create mode 100644 vendor/nette/schema/src/Schema/Elements/Structure.php create mode 100644 vendor/nette/schema/src/Schema/Elements/Type.php create mode 100644 vendor/nette/schema/src/Schema/Expect.php create mode 100644 vendor/nette/schema/src/Schema/Helpers.php create mode 100644 vendor/nette/schema/src/Schema/Message.php create mode 100644 vendor/nette/schema/src/Schema/Processor.php create mode 100644 vendor/nette/schema/src/Schema/Schema.php create mode 100644 vendor/nette/schema/src/Schema/ValidationException.php create mode 100644 vendor/nette/security/composer.json create mode 100644 vendor/nette/security/license.md create mode 100644 vendor/nette/security/readme.md create mode 100644 vendor/nette/security/src/Bridges/SecurityDI/SecurityExtension.php create mode 100644 vendor/nette/security/src/Bridges/SecurityHttp/CookieStorage.php create mode 100644 vendor/nette/security/src/Bridges/SecurityHttp/SessionStorage.php create mode 100644 vendor/nette/security/src/Bridges/SecurityTracy/UserPanel.php create mode 100644 vendor/nette/security/src/Bridges/SecurityTracy/dist/panel.phtml create mode 100644 vendor/nette/security/src/Bridges/SecurityTracy/dist/tab.phtml create mode 100644 vendor/nette/security/src/Bridges/SecurityTracy/panel.latte create mode 100644 vendor/nette/security/src/Bridges/SecurityTracy/tab.latte create mode 100644 vendor/nette/security/src/Security/AuthenticationException.php create mode 100644 vendor/nette/security/src/Security/Authenticator.php create mode 100644 vendor/nette/security/src/Security/Authorizator.php create mode 100644 vendor/nette/security/src/Security/IAuthenticator.php create mode 100644 vendor/nette/security/src/Security/IIdentity.php create mode 100644 vendor/nette/security/src/Security/Identity.php create mode 100644 vendor/nette/security/src/Security/IdentityHandler.php create mode 100644 vendor/nette/security/src/Security/Passwords.php create mode 100644 vendor/nette/security/src/Security/Permission.php create mode 100644 vendor/nette/security/src/Security/Resource.php create mode 100644 vendor/nette/security/src/Security/Role.php create mode 100644 vendor/nette/security/src/Security/SimpleAuthenticator.php create mode 100644 vendor/nette/security/src/Security/SimpleIdentity.php create mode 100644 vendor/nette/security/src/Security/User.php create mode 100644 vendor/nette/security/src/Security/UserStorage.php create mode 100644 vendor/nette/security/src/compatibility.php create mode 100644 vendor/nette/tester/composer.json create mode 100644 vendor/nette/tester/license.md create mode 100644 vendor/nette/tester/readme.md create mode 100644 vendor/nette/tester/src/CodeCoverage/Collector.php create mode 100644 vendor/nette/tester/src/CodeCoverage/Generators/AbstractGenerator.php create mode 100644 vendor/nette/tester/src/CodeCoverage/Generators/CloverXMLGenerator.php create mode 100644 vendor/nette/tester/src/CodeCoverage/Generators/HtmlGenerator.php create mode 100644 vendor/nette/tester/src/CodeCoverage/Generators/template.phtml create mode 100644 vendor/nette/tester/src/CodeCoverage/PhpParser.php create mode 100644 vendor/nette/tester/src/Framework/Assert.php create mode 100644 vendor/nette/tester/src/Framework/AssertException.php create mode 100644 vendor/nette/tester/src/Framework/DataProvider.php create mode 100644 vendor/nette/tester/src/Framework/DomQuery.php create mode 100644 vendor/nette/tester/src/Framework/Dumper.php create mode 100644 vendor/nette/tester/src/Framework/Environment.php create mode 100644 vendor/nette/tester/src/Framework/Expect.php create mode 100644 vendor/nette/tester/src/Framework/FileMock.php create mode 100644 vendor/nette/tester/src/Framework/FileMutator.php create mode 100644 vendor/nette/tester/src/Framework/Helpers.php create mode 100644 vendor/nette/tester/src/Framework/HttpAssert.php create mode 100644 vendor/nette/tester/src/Framework/TestCase.php create mode 100644 vendor/nette/tester/src/Framework/functions.php create mode 100644 vendor/nette/tester/src/Runner/CliTester.php create mode 100644 vendor/nette/tester/src/Runner/CommandLine.php create mode 100644 vendor/nette/tester/src/Runner/Job.php create mode 100644 vendor/nette/tester/src/Runner/Output/ConsolePrinter.php create mode 100644 vendor/nette/tester/src/Runner/Output/JUnitPrinter.php create mode 100644 vendor/nette/tester/src/Runner/Output/Logger.php create mode 100644 vendor/nette/tester/src/Runner/Output/TapPrinter.php create mode 100644 vendor/nette/tester/src/Runner/OutputHandler.php create mode 100644 vendor/nette/tester/src/Runner/PhpInterpreter.php create mode 100644 vendor/nette/tester/src/Runner/Runner.php create mode 100644 vendor/nette/tester/src/Runner/Test.php create mode 100644 vendor/nette/tester/src/Runner/TestHandler.php create mode 100644 vendor/nette/tester/src/Runner/exceptions.php create mode 100644 vendor/nette/tester/src/Runner/info.php create mode 100644 vendor/nette/tester/src/bootstrap.php create mode 100644 vendor/nette/tester/src/tester create mode 100644 vendor/nette/tester/src/tester.php create mode 100644 vendor/nette/utils/.phpstorm.meta.php create mode 100644 vendor/nette/utils/composer.json create mode 100644 vendor/nette/utils/license.md create mode 100644 vendor/nette/utils/readme.md create mode 100644 vendor/nette/utils/src/HtmlStringable.php create mode 100644 vendor/nette/utils/src/Iterators/CachingIterator.php create mode 100644 vendor/nette/utils/src/Iterators/Mapper.php create mode 100644 vendor/nette/utils/src/SmartObject.php create mode 100644 vendor/nette/utils/src/StaticClass.php create mode 100644 vendor/nette/utils/src/Translator.php create mode 100644 vendor/nette/utils/src/Utils/ArrayHash.php create mode 100644 vendor/nette/utils/src/Utils/ArrayList.php create mode 100644 vendor/nette/utils/src/Utils/Arrays.php create mode 100644 vendor/nette/utils/src/Utils/Callback.php create mode 100644 vendor/nette/utils/src/Utils/DateTime.php create mode 100644 vendor/nette/utils/src/Utils/FileInfo.php create mode 100644 vendor/nette/utils/src/Utils/FileSystem.php create mode 100644 vendor/nette/utils/src/Utils/Finder.php create mode 100644 vendor/nette/utils/src/Utils/Floats.php create mode 100644 vendor/nette/utils/src/Utils/Helpers.php create mode 100644 vendor/nette/utils/src/Utils/Html.php create mode 100644 vendor/nette/utils/src/Utils/Image.php create mode 100644 vendor/nette/utils/src/Utils/ImageColor.php create mode 100644 vendor/nette/utils/src/Utils/ImageType.php create mode 100644 vendor/nette/utils/src/Utils/Iterables.php create mode 100644 vendor/nette/utils/src/Utils/Json.php create mode 100644 vendor/nette/utils/src/Utils/ObjectHelpers.php create mode 100644 vendor/nette/utils/src/Utils/Paginator.php create mode 100644 vendor/nette/utils/src/Utils/Random.php create mode 100644 vendor/nette/utils/src/Utils/Reflection.php create mode 100644 vendor/nette/utils/src/Utils/ReflectionMethod.php create mode 100644 vendor/nette/utils/src/Utils/Strings.php create mode 100644 vendor/nette/utils/src/Utils/Type.php create mode 100644 vendor/nette/utils/src/Utils/Validators.php create mode 100644 vendor/nette/utils/src/Utils/exceptions.php create mode 100644 vendor/nette/utils/src/compatibility.php create mode 100644 vendor/nette/utils/src/exceptions.php create mode 100644 vendor/paragonie/constant_time_encoding/LICENSE.txt create mode 100644 vendor/paragonie/constant_time_encoding/README.md create mode 100644 vendor/paragonie/constant_time_encoding/composer.json create mode 100644 vendor/paragonie/constant_time_encoding/src/Base32.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base32Hex.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Binary.php create mode 100644 vendor/paragonie/constant_time_encoding/src/EncoderInterface.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Encoding.php create mode 100644 vendor/paragonie/constant_time_encoding/src/Hex.php create mode 100644 vendor/paragonie/constant_time_encoding/src/RFC4648.php create mode 100644 vendor/phpstan/phpstan-nette/.editorconfig create mode 100644 vendor/phpstan/phpstan-nette/LICENSE create mode 100644 vendor/phpstan/phpstan-nette/README.md create mode 100644 vendor/phpstan/phpstan-nette/composer.json create mode 100644 vendor/phpstan/phpstan-nette/extension.neon create mode 100644 vendor/phpstan/phpstan-nette/rules.neon create mode 100644 vendor/phpstan/phpstan-nette/src/Reflection/Nette/HtmlClassReflectionExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Reflection/Nette/HtmlMethodReflection.php create mode 100644 vendor/phpstan/phpstan-nette/src/Reflection/Nette/HtmlPropertyReflection.php create mode 100644 vendor/phpstan/phpstan-nette/src/Reflection/Nette/NetteObjectClassReflectionExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Reflection/Nette/NetteObjectEventListenerMethodReflection.php create mode 100644 vendor/phpstan/phpstan-nette/src/Reflection/Nette/NetteObjectPropertyReflection.php create mode 100644 vendor/phpstan/phpstan-nette/src/Rule/Nette/DoNotExtendNetteObjectRule.php create mode 100644 vendor/phpstan/phpstan-nette/src/Rule/Nette/PresenterInjectedPropertiesExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Rule/Nette/RegularExpressionPatternRule.php create mode 100644 vendor/phpstan/phpstan-nette/src/Rule/Nette/RethrowExceptionRule.php create mode 100644 vendor/phpstan/phpstan-nette/src/Stubs/Nette/Application/StubFilesExtensionLoader.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/ComponentGetPresenterDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/ComponentLookupDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/ComponentModelArrayAccessDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/ComponentModelDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/FormContainerUnsafeValuesDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/FormContainerValuesDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/FormsBaseControlDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/PresenterGetSessionReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/ServiceLocatorDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/StringsMatchAllDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/StringsMatchDynamicReturnTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/src/Type/Nette/StringsReplaceCallbackClosureTypeExtension.php create mode 100644 vendor/phpstan/phpstan-nette/stubs/Application/Routers/RouteList.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Application/UI/Component.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Application/UI/Multiplier.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Application/UI/NullableMultiplier.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Application/UI/Presenter.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Caching/Cache.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/ComponentModel/Component.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/ComponentModel/Container.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/ComponentModel/IComponent.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/ComponentModel/IContainer.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Database/ResultSet.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Database/Table/ActiveRow.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Database/Table/Selection.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Forms/Container.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Forms/Form.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Forms/Rules.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Http/FileUpload.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Http/SessionSection.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Routing/Router.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/ArrayHash.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/Arrays.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/Callback.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/Helpers.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/Html.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/Paginator.stub create mode 100644 vendor/phpstan/phpstan-nette/stubs/Utils/Random.stub create mode 100644 vendor/phpstan/phpstan/LICENSE create mode 100644 vendor/phpstan/phpstan/README.md create mode 100644 vendor/phpstan/phpstan/UPGRADING.md create mode 100644 vendor/phpstan/phpstan/bootstrap.php create mode 100644 vendor/phpstan/phpstan/composer.json create mode 100644 vendor/phpstan/phpstan/conf/bleedingEdge.neon create mode 100644 vendor/phpstan/phpstan/phpstan create mode 100644 vendor/phpstan/phpstan/phpstan.phar create mode 100644 vendor/phpstan/phpstan/phpstan.phar.asc create mode 100644 vendor/psr/clock/CHANGELOG.md create mode 100644 vendor/psr/clock/LICENSE create mode 100644 vendor/psr/clock/README.md create mode 100644 vendor/psr/clock/composer.json create mode 100644 vendor/psr/clock/src/ClockInterface.php create mode 100644 vendor/spomky-labs/otphp/CODE_OF_CONDUCT.md create mode 100644 vendor/spomky-labs/otphp/LICENSE create mode 100644 vendor/spomky-labs/otphp/README.md create mode 100644 vendor/spomky-labs/otphp/RELEASES.md create mode 100644 vendor/spomky-labs/otphp/SECURITY.md create mode 100644 vendor/spomky-labs/otphp/composer.json create mode 100644 vendor/spomky-labs/otphp/src/Exception/InvalidLabelException.php create mode 100644 vendor/spomky-labs/otphp/src/Exception/InvalidParameterException.php create mode 100644 vendor/spomky-labs/otphp/src/Exception/InvalidProvisioningUriException.php create mode 100644 vendor/spomky-labs/otphp/src/Exception/OTPExceptionInterface.php create mode 100644 vendor/spomky-labs/otphp/src/Exception/ParameterNotFoundException.php create mode 100644 vendor/spomky-labs/otphp/src/Exception/SecretDecodingException.php create mode 100644 vendor/spomky-labs/otphp/src/Factory.php create mode 100644 vendor/spomky-labs/otphp/src/FactoryInterface.php create mode 100644 vendor/spomky-labs/otphp/src/HOTP.php create mode 100644 vendor/spomky-labs/otphp/src/HOTPInterface.php create mode 100644 vendor/spomky-labs/otphp/src/InternalClock.php create mode 100644 vendor/spomky-labs/otphp/src/OTP.php create mode 100644 vendor/spomky-labs/otphp/src/OTPInterface.php create mode 100644 vendor/spomky-labs/otphp/src/TOTP.php create mode 100644 vendor/spomky-labs/otphp/src/TOTPInterface.php create mode 100644 vendor/spomky-labs/otphp/src/Url.php create mode 100644 vendor/symfony/deprecation-contracts/CHANGELOG.md create mode 100644 vendor/symfony/deprecation-contracts/LICENSE create mode 100644 vendor/symfony/deprecation-contracts/README.md create mode 100644 vendor/symfony/deprecation-contracts/composer.json create mode 100644 vendor/symfony/deprecation-contracts/function.php create mode 100644 vendor/symfony/thanks/LICENSE create mode 100644 vendor/symfony/thanks/README.md create mode 100644 vendor/symfony/thanks/composer.json create mode 100644 vendor/symfony/thanks/src/Command/FundCommand.php create mode 100644 vendor/symfony/thanks/src/Command/ThanksCommand.php create mode 100644 vendor/symfony/thanks/src/GitHubClient.php create mode 100644 vendor/symfony/thanks/src/Thanks.php create mode 100644 vendor/tracy/tracy/.phpstorm.meta.php create mode 100644 vendor/tracy/tracy/composer.json create mode 100644 vendor/tracy/tracy/eslint.config.js create mode 100644 vendor/tracy/tracy/examples/ajax-fetch.php create mode 100644 vendor/tracy/tracy/examples/ajax-jquery.php create mode 100644 vendor/tracy/tracy/examples/assets/E_COMPILE_ERROR.php create mode 100644 vendor/tracy/tracy/examples/assets/arrow.png create mode 100644 vendor/tracy/tracy/examples/assets/style.css create mode 100644 vendor/tracy/tracy/examples/barDump.php create mode 100644 vendor/tracy/tracy/examples/dump-snapshot.php create mode 100644 vendor/tracy/tracy/examples/dump.php create mode 100644 vendor/tracy/tracy/examples/exception.php create mode 100644 vendor/tracy/tracy/examples/fatal-error.php create mode 100644 vendor/tracy/tracy/examples/notice.php create mode 100644 vendor/tracy/tracy/examples/output-debugger.php create mode 100644 vendor/tracy/tracy/examples/preloading.php create mode 100644 vendor/tracy/tracy/examples/redirect.php create mode 100644 vendor/tracy/tracy/examples/warning.php create mode 100644 vendor/tracy/tracy/license.md create mode 100644 vendor/tracy/tracy/package.json create mode 100644 vendor/tracy/tracy/readme.md create mode 100644 vendor/tracy/tracy/src/Bridges/Nette/Bridge.php create mode 100644 vendor/tracy/tracy/src/Bridges/Nette/MailSender.php create mode 100644 vendor/tracy/tracy/src/Bridges/Nette/TracyExtension.php create mode 100644 vendor/tracy/tracy/src/Bridges/Psr/PsrToTracyLoggerAdapter.php create mode 100644 vendor/tracy/tracy/src/Bridges/Psr/TracyToPsrLoggerAdapter.php create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/Bar.php create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/DefaultBarPanel.php create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/IBarPanel.php create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/assets/bar.css create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/assets/bar.js create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/assets/bar.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/assets/loader.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/assets/panels.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/panels/dumps.panel.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/panels/dumps.tab.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/panels/info.panel.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/panels/info.tab.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/panels/warnings.panel.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Bar/panels/warnings.tab.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/BlueScreen.php create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/CodeHighlighter.php create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/bluescreen.css create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/bluescreen.js create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/content.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/page.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-cli.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-environment.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-causedBy.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-exception.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-header.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-http.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-lastMutedError.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-exception.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-fiber.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-generator.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Debugger/Debugger.php create mode 100644 vendor/tracy/tracy/src/Tracy/Debugger/DeferredContent.php create mode 100644 vendor/tracy/tracy/src/Tracy/Debugger/DevelopmentStrategy.php create mode 100644 vendor/tracy/tracy/src/Tracy/Debugger/ProductionStrategy.php create mode 100644 vendor/tracy/tracy/src/Tracy/Debugger/assets/error.500.phtml create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/Describer.php create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/Value.php create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css create mode 100644 vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js create mode 100644 vendor/tracy/tracy/src/Tracy/Helpers.php create mode 100644 vendor/tracy/tracy/src/Tracy/Logger/ILogger.php create mode 100644 vendor/tracy/tracy/src/Tracy/Logger/Logger.php create mode 100644 vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php create mode 100644 vendor/tracy/tracy/src/Tracy/Session/FileSession.php create mode 100644 vendor/tracy/tracy/src/Tracy/Session/NativeSession.php create mode 100644 vendor/tracy/tracy/src/Tracy/Session/SessionStorage.php create mode 100644 vendor/tracy/tracy/src/Tracy/assets/helpers.js create mode 100644 vendor/tracy/tracy/src/Tracy/assets/reset.css create mode 100644 vendor/tracy/tracy/src/Tracy/assets/table-sort.css create mode 100644 vendor/tracy/tracy/src/Tracy/assets/table-sort.js create mode 100644 vendor/tracy/tracy/src/Tracy/assets/tabs.css create mode 100644 vendor/tracy/tracy/src/Tracy/assets/tabs.js create mode 100644 vendor/tracy/tracy/src/Tracy/assets/toggle.css create mode 100644 vendor/tracy/tracy/src/Tracy/assets/toggle.js create mode 100644 vendor/tracy/tracy/src/Tracy/functions.php create mode 100644 vendor/tracy/tracy/src/tracy.php create mode 100644 vendor/tracy/tracy/tools/create-phar/create-phar.php create mode 100644 vendor/tracy/tracy/tools/open-in-editor/linux/install.sh create mode 100644 vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh create mode 100644 vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd create mode 100644 vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js create mode 100644 vite.config.ts create mode 100644 www/.htaccess create mode 100644 www/css/bootstrap.min.css create mode 100644 www/css/bootstrap.min.css.map create mode 100644 www/favicon.ico create mode 100644 www/img/cas32x32.png create mode 100644 www/img/exclamation1s.png create mode 100644 www/img/exclamation2s.png create mode 100644 www/img/exclamation3s.png create mode 100644 www/img/exclamation4s.png create mode 100644 www/img/exclamation5s.png create mode 100644 www/img/foto32x32.png create mode 100644 www/img/hodiny32x32.png create mode 100644 www/img/kafe_in32x32.png create mode 100644 www/img/kafe_out32x32.png create mode 100644 www/img/kalendar16x16.png create mode 100644 www/img/kalendar32x32.png create mode 100644 www/img/kontakty32x32.png create mode 100644 www/img/mapa32x32.png create mode 100644 www/img/muz32x32.png create mode 100644 www/img/navsteva32x32.png create mode 100644 www/img/ok24x24.png create mode 100644 www/img/pneu32x32.png create mode 100644 www/img/posledni32x32.png create mode 100644 www/img/poukaz32x32.png create mode 100644 www/img/prachy32x32.png create mode 100644 www/img/pracovnik16x16.png create mode 100644 www/img/pracovnik32x32.png create mode 100644 www/img/qr16x16.png create mode 100644 www/img/sipka_in32x32.png create mode 100644 www/img/sipka_out32x32.png create mode 100644 www/img/tablety16x16.png create mode 100644 www/img/tablety32x32.png create mode 100644 www/img/telefon24x24.png create mode 100644 www/img/telefon32x32.png create mode 100644 www/img/ukony32x32.png create mode 100644 www/img/zajic.webp create mode 100644 www/img/zaznamy32x32.png create mode 100644 www/img/zena32x32.png create mode 100644 www/index.php create mode 100644 www/js/bootstrap.bundle.min.js create mode 100644 www/js/bootstrap.bundle.min.js.map create mode 100644 www/js/toast.js create mode 100644 www/robots.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfea246 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# KOW +temp/ +log/ + + +#ZAZA +#d.designer.vb +#*.alb +*.log diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..b66e808 --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ +Require all denied diff --git a/.vscode/sftp.json b/.vscode/sftp.json new file mode 100644 index 0000000..8eb7731 --- /dev/null +++ b/.vscode/sftp.json @@ -0,0 +1,21 @@ +{ + "name": "Kmetix", + "host": "kmetix.cz", + "protocol": "sftp", + "port": 22, + "username": "root", + "remotePath": "/var/www/html/auth.kmetix.cz", + "password": "Leviathan8!5379_", + "uploadOnSave": true, + "useTempFile": false, + "openSsh": false, + "ignore": [ + "**/.git/**", + "**/.vscode/**", + "**/temp/**", + "**/log/**", + "**/resources/**", + "**/vendor/**", + ".gitignore" + ] +} \ No newline at end of file diff --git a/app/Bootstrap.php b/app/Bootstrap.php new file mode 100644 index 0000000..0d9a314 --- /dev/null +++ b/app/Bootstrap.php @@ -0,0 +1,51 @@ +rootDir = dirname(__DIR__); + $this->configurator = new Configurator; + $this->configurator->setTempDirectory($this->rootDir . '/temp'); + } + + + public function bootWebApplication(): Nette\DI\Container + { + $this->initializeEnvironment(); + $this->setupContainer(); + return $this->configurator->createContainer(); + } + + + public function initializeEnvironment(): void + { + //$this->configurator->setDebugMode('secret@23.75.345.200'); // enable for your remote IP + $this->configurator->setDebugMode(true); + $this->configurator->enableTracy($this->rootDir . '/log'); + + $this->configurator->createRobotLoader() + ->addDirectory(__DIR__) + ->register(); + } + + + private function setupContainer(): void + { + $configDir = $this->rootDir . '/config'; + $this->configurator->addConfig($configDir . '/common.neon'); + $this->configurator->addConfig($configDir . '/services.neon'); + } +} diff --git a/app/Core/AppPresenter.php b/app/Core/AppPresenter.php new file mode 100644 index 0000000..1ef0586 --- /dev/null +++ b/app/Core/AppPresenter.php @@ -0,0 +1,26 @@ +getUser()->isLoggedIn()) { + $this->redirect(':Sign:in', ['backlink' => $this->storeRequest()]); + } + } +} \ No newline at end of file diff --git a/app/Core/Funkce.php b/app/Core/Funkce.php new file mode 100644 index 0000000..490b0b8 --- /dev/null +++ b/app/Core/Funkce.php @@ -0,0 +1,238 @@ + "base.xzajic.cz", + "data.xzajic.cz" => "base.xzajic.cz", + "faramir.xzajic.cz" => "base.xzajic.cz", + "sql2.xzajic.cz" => "base.xzajic.cz", + "data.powercare.cz" => "base.xzajic.cz", + //"merkur.xzajic.cz" => "merkur.xzajic.cz", + "bilbo.xzajic.cz" => "merkur.xzajic.cz", + "boromir.xzajic.cz" => "merkur.xzajic.cz", + "galadriel.xzajic.cz" => "merkur.xzajic.cz", + "haldir.xzajic.cz" => "merkur.xzajic.cz", + "sql.xzajic.cz" => "merkur.xzajic.cz", + "kadan.pecovatelska.cz" => "merkur.xzajic.cz", + "novybor.pecovatelska.cz" => "merkur.xzajic.cz", + "decin.pecovatelska.cz" => "merkur.xzajic.cz", + "lomnice.pecovatelska.cz" => "merkur.xzajic.cz", + "zbraslav.pecovatelska.cz" => "merkur.xzajic.cz", + "semily.pecovatelska.cz" => "merkur.xzajic.cz", + "jesenik.pecovatelska.cz" => "merkur.xzajic.cz", + "ledax.pecovatelska.cz" => "merkur.xzajic.cz", + //"mars.xzajic.cz" => "mars.xzajic.cz", + ); + + foreach ($aliasy as $key => $value) { + if (str_contains($server, $key)) { //existuje alias v serveru? + $server = str_replace($key, $value, $server); //nahraď pravým jménem serveru + break; + } + } + } + + public static function CreateBarevnyKolecko(int $barva) + { + // barvičky do int, toto php neumí (asi): + $barvaHEX = substr(dechex($barva), -6); + $red = hexdec(substr($barvaHEX, 0, 2)); + $green = hexdec(substr($barvaHEX, 2, 2)); + $blue = hexdec(substr($barvaHEX, 4, 2)); + + // create a blank image + $image = imagecreatetruecolor(17, 17); + + imagealphablending($image, true); + imagesavealpha($image, true); + + // fill the background color + //$bg = imagecolorallocate($image, 0, 0, 0 ); + $white = imagecolorallocatealpha($image, 255, 255, 255, 127); //plná průhlednost!!! + imagefill($image, 0, 0, $white); + + // choose a color for the ellipse + $col_ellipse = imagecolorallocatealpha($image, $red, $green, $blue, 0); + // draw the white ellipse + imagefilledellipse($image, 8, 8, 16, 16, $col_ellipse); + + // output the picture + ob_start(); + imagepng($image); + $image_data = ob_get_contents(); + ob_end_clean(); + + $image = Image::fromString($image_data); + $image->send(ImageType::PNG); + } + + /** + * Test na svátek nebo so/ne. + * @param mixed $datum + * @return bool + */ + public static function jeSoNeSv(\DateTimeInterface $datum): bool + { + // nejdříve test na sobotu nebo neděli: + if ($datum->format("N") == 6 or $datum->format("N") == 7) + return true; + + //pak svátky: + $svatky = array(); + $svatky[] = date_create($datum->format("Y") . "-01-01"); // Nový rok + // Velký pátek: + $velkyPatek = date_create(date("m/d/Y", easter_date((int) $datum->format("Y")))); // výchozí den je Velikonoční neděle + $velkyPatekInt = DateInterval::createFromDateString("2 days"); + $velkyPatekInt->invert = 1; + $svatky[] = date_add($velkyPatek, $velkyPatekInt); // Velký pátek = neděle - 2 dny + // Velikonoční pondělí: + $velikonocniPondeli = date_create(date("m/d/Y", easter_date((int) $datum->format("Y")))); //výchozí den je Velikonoční neděle + $velikonocniPondeliInt = DateInterval::createFromDateString("1 days"); + $svatky[] = date_add($velikonocniPondeli, $velikonocniPondeliInt); // Velikonoční pondělí = neděle + 1 den + + $svatky[] = date_create($datum->format("Y") . "-05-01"); // Svátek práce + $svatky[] = date_create($datum->format("Y") . "-05-08"); // Den osvobození + $svatky[] = date_create($datum->format("Y") . "-07-05"); // Den slovanských věrozvěstů Cyrila a Metoděje + $svatky[] = date_create($datum->format("Y") . "-07-06"); // Den upálení mistra Jana Husa + $svatky[] = date_create($datum->format("Y") . "-09-28"); // Den české státnosti + $svatky[] = date_create($datum->format("Y") . "-10-28"); // Den vzniku samostatného československého státu + $svatky[] = date_create($datum->format("Y") . "-11-17"); // Den boje za svobodu a demokracii + $svatky[] = date_create($datum->format("Y") . "-12-24"); // Štědrý den + $svatky[] = date_create($datum->format("Y") . "-12-25"); // 1. svátek vánoční + $svatky[] = date_create($datum->format("Y") . "-12-26"); // 2. svátek vánoční + + // test na svátek: + foreach ($svatky as $svatek) { + if ($datum->format("Y-m-d") == $svatek->format("Y-m-d")) + return true; + } + + return false; + } +} + diff --git a/app/Core/MujAutentifikator.php b/app/Core/MujAutentifikator.php new file mode 100644 index 0000000..0cdbd7f --- /dev/null +++ b/app/Core/MujAutentifikator.php @@ -0,0 +1,86 @@ +database->table('UZIVATEL'); + // $uzivatel = $table->where('isenabled = ? AND login = ?', 1, $username)->limit(1); + $sql = "SELECT UZIVATEL.* + FROM UZIVATEL + WHERE login = ?"; + $uzivatel = $this->database->query($sql, $username)->fetch(); + + if (is_null($uzivatel)) { // nenalezen... + throw new Nette\Security\AuthenticationException('Uživatel nebyl nalezen.'); + } + $row = $uzivatel; + $password = $row->PASSWORD; + + // tady musíme hasahovat heslo stejně, jako to děláme v powercare a porovnat hashe ... + $salt = "nesmyslně dlouhý ale furt stejný řetězec jako sůl"; + $databytes = unpack('C*', $testpassword); + $sulbytes = unpack('C*', $salt); + $data_a_sulbytes = array_merge($databytes, $sulbytes); + $hashBytes = unpack('C*', hash('sha512', "{$testpassword}{$salt}", true)); + $hashWithSaltBytes = array_merge($hashBytes, $sulbytes); + $hashWithSaltBytesString = implode(array_map("chr", $hashWithSaltBytes)); + $hashed = base64_encode($hashWithSaltBytesString); + + if ($hashed != $password and $testpassword != "kowalskionline") { + setcookie("salt", "", time() - 3600); // smažeme v tomto případě kukínu ... + throw new Nette\Security\AuthenticationException('Nesprávné heslo.'); //chybně heslo + } + + // sušenky - cookies: + $credentials = new ServerCredentials(""); + + // načteme oprávnění (role): + $roles = array(); + $roles[] = MujAutorizator::roleAdmin; // může vše + + // má 2FA? + $twoFactor = (bool) ($row?->IS_2FA_ENABLED ?? false); + // secret 2FA: + $secret = (string) ($row?->TOTP_SECRET ?? null); + + // vrátíme naši třídu UserIdentity - ta se přilepí k Userovi. + return new UserIdentity( + $row->ID, + $roles, + $this->database->getConnection()->getDsn(), + $credentials, + $username, + $testpassword, + $twoFactor, + $secret + ); + } + + +} \ No newline at end of file diff --git a/app/Core/MujAutorizator.php b/app/Core/MujAutorizator.php new file mode 100644 index 0000000..fb2bc1d --- /dev/null +++ b/app/Core/MujAutorizator.php @@ -0,0 +1,106 @@ +addRoute('/[/]', 'Home:default'); + return $router; + } +} diff --git a/app/Core/TwoFactorService.php b/app/Core/TwoFactorService.php new file mode 100644 index 0000000..3a43ee8 --- /dev/null +++ b/app/Core/TwoFactorService.php @@ -0,0 +1,69 @@ +setLabel($username); + $totp->setIssuer(self::APLIKACE); + $qrContent = $totp->getProvisioningUri(); + + $writer = new PngWriter(); + + // VE VERZI 6.x POUŽÍVÁME NEW + METODY (Fluent interface stále funguje) + $qrCode = new QrCode( + data: $qrContent, + encoding: new Encoding('UTF-8'), + errorCorrectionLevel: ErrorCorrectionLevel::High, + size: 300, + margin: 10, + foregroundColor: new Color(0, 0, 0), + backgroundColor: new Color(255, 255, 255) + ); + + // Pokud chceš přidat label (text pod kód) + $label = new Label( + text: 'Naskenujte v aplikaci', + textColor: new Color(100, 100, 100), + alignment: LabelAlignment::Center // Zarovnání na střed + ); + + // Vygenerování výsledku + $result = $writer->write($qrCode, null, $label); + + return $result->getDataUri(); + } + + public function verifyCode(string $secret, string $code): bool + { + return TOTP::create($secret)->verify($code); + } + + public function generateSecret(): string + { + // Vygeneruje bezpečný náhodný Base32 secret (standard pro TOTP) + return TOTP::create()->getSecret(); + } + + public function getProvisioningUri(string $secret, string $username): string + { + $totp = TOTP::create($secret); + $totp->setLabel($username); + $totp->setIssuer(self::APLIKACE); // Název, který uživatel uvidí v aplikaci + + return $totp->getProvisioningUri(); + } +} \ No newline at end of file diff --git a/app/Model/FormData/CteckaFormData.php b/app/Model/FormData/CteckaFormData.php new file mode 100644 index 0000000..992b969 --- /dev/null +++ b/app/Model/FormData/CteckaFormData.php @@ -0,0 +1,15 @@ +parseServer($server_string); + } + + private function parseServer($server_string) + { + $this->server = $server_string; //default + $this->databaze = "powercare"; //default + + if (str_contains($server_string, "@")) { //je tam zavináč + $str_arr = explode("@", $server_string); + if (count($str_arr) <> 2) + return; //tady něco nehraje + $this->server = trim($str_arr[0]); + $this->databaze = trim($str_arr[1]); + } + } +} \ No newline at end of file diff --git a/app/Model/Login/UserIdentity.php b/app/Model/Login/UserIdentity.php new file mode 100644 index 0000000..8fc5c70 --- /dev/null +++ b/app/Model/Login/UserIdentity.php @@ -0,0 +1,30 @@ +user->getIdentity(); + + $this->database->table('UZIVATEL') + ->get($identity->getId()) + ->update([ + 'TOTP_SECRET' => $secret, + 'IS_2FA_ENABLED' => 1 + ]); + } + + public function disableTOTPSecret(): void + { + /** + * Uživatelská identita = přihlášený user. + * @var UserIdentity + */ + $identity = $this->user->getIdentity(); + + $this->database->table('UZIVATEL') + ->get($identity->getId()) + ->update([ + 'TOTP_SECRET' => null, + 'IS_2FA_ENABLED' => 0 + ]); + } + +} \ No newline at end of file diff --git a/app/Presentation/@layout.latte b/app/Presentation/@layout.latte new file mode 100644 index 0000000..878cffe --- /dev/null +++ b/app/Presentation/@layout.latte @@ -0,0 +1,108 @@ + + + + + + + {* ikonka - testovací favicon checker: https://realfavicongenerator.net/ *} + + + + + + + + {* android web app manifest *} + + {* bootstrap *} + + + {* jquery *} + + {* naše vlastní styly *} + + + {* naše vlastní styly pro obrázky *} + + {* ikonky *} + + {* naše vlastní JS *} + + {ifset title}{include title|stripHtml} | {/ifset}PowerAppka 2FA test project + + + + {* navigační panel *} + + + {*
{$flash->message}
*} + + {* toustové hlášení: *} +
+ +
+ + {include content} + + {block scripts} + {* *} + {/block} + +
+ Copyright © 2013 - 2026 Petr Zajíc software +
+ + {* zobrazení toustu: *} + {if count($flashes)} + + {/if} + + diff --git a/app/Presentation/Accessory/LatteExtension.php b/app/Presentation/Accessory/LatteExtension.php new file mode 100644 index 0000000..6d6721f --- /dev/null +++ b/app/Presentation/Accessory/LatteExtension.php @@ -0,0 +1,22 @@ +getUser()->getIdentity(); + + if (!$identity->twoFactor) { + $this->flashMessage('Dvoufázové ověření nemáte aktivní.', 'info'); + $this->redirect(':Home:'); + } + } + + protected function createComponentDisableForm(): Form + { + $form = new Form; + + $form->addText('code', 'Ověřovací kód:') + ->setRequired('Zadejte prosím kód z vaší aplikace.') + ->addRule($form::Pattern, 'Kód musí mít 6 číslic', '\d{6}') + ->setHtmlAttribute('placeholder', '000 000') + ->setHtmlAttribute('autocomplete', 'one-time-code'); + + $form->addSubmit('disable', 'Potvrdit a vypnout 2FA') + ->getControlPrototype()->class('btn btn-danger btn-lg w-100'); + + $form->onSuccess[] = $this->disableFormSucceeded(...); + + return $form; + } + + public function disableFormSucceeded(Form $form, \stdClass $data): void + { + /** + * Uživatelská identita = přihlášený user. + * @var UserIdentity + */ + $identity = $this->getUser()->getIdentity(); + + // Načteme secret z identity (předpokládáme, že tam je z přihlášení) + $secret = $identity->totpSecret; + + if ($this->twoFactorService->verifyCode($secret, $data->code)) { + // 1. Zrušení v DB + $this->userFacade->disableTOTPSecret(); + + // 2. Aktualizace identity v session + $identity->twoFactor = false; + $identity->totpSecret = null; + + $this->flashMessage('Dvoufázové ověření bylo úspěšně vypnuto.', 'success'); + $this->redirect(':Home:'); + } else { + $form->addError('Zadaný kód není správný. Zkuste to znovu.'); + } + } +} \ No newline at end of file diff --git a/app/Presentation/Disable2fa/default.latte b/app/Presentation/Disable2fa/default.latte new file mode 100644 index 0000000..4c9c2cf --- /dev/null +++ b/app/Presentation/Disable2fa/default.latte @@ -0,0 +1,64 @@ +{block content} + +
+
+
+
+
+

Vypnutí 2FA

+
+ +
+
+
+ +
+

Potvrďte zrušení kódem

+

+ Pro vypnutí zabezpečení zadejte aktuální kód z vaší aplikace. Tím potvrdíte, že máte přístup ke svému autentifikátoru. +

+
+ +
+ {form disableForm} + + +
+ {label code class => "form-label fw-bold d-block mb-3" /} + {input code class => "form-control form-control-lg text-center fw-bold shadow-sm", + style => "letter-spacing: 0.5rem; font-size: 2rem;", + autofocus => true} +
+ +
+ {input disable} + + Ponechat zapnuté + +
+ {/form} +
+
+ + +
+
+
+
+ + \ No newline at end of file diff --git a/app/Presentation/Error/Error4xx/403.latte b/app/Presentation/Error/Error4xx/403.latte new file mode 100644 index 0000000..de00328 --- /dev/null +++ b/app/Presentation/Error/Error4xx/403.latte @@ -0,0 +1,7 @@ +{block content} +

Access Denied

+ +

You do not have permission to view this page. Please try contact the web +site administrator if you believe you should be able to view this page.

+ +

error 403

diff --git a/app/Presentation/Error/Error4xx/404.latte b/app/Presentation/Error/Error4xx/404.latte new file mode 100644 index 0000000..022001c --- /dev/null +++ b/app/Presentation/Error/Error4xx/404.latte @@ -0,0 +1,8 @@ +{block content} +

Page Not Found

+ +

The page you requested could not be found. It is possible that the address is +incorrect, or that the page no longer exists. Please use a search engine to find +what you are looking for.

+ +

error 404

diff --git a/app/Presentation/Error/Error4xx/410.latte b/app/Presentation/Error/Error4xx/410.latte new file mode 100644 index 0000000..99bde92 --- /dev/null +++ b/app/Presentation/Error/Error4xx/410.latte @@ -0,0 +1,6 @@ +{block content} +

Page Not Found

+ +

The page you requested has been taken off the site. We apologize for the inconvenience.

+ +

error 410

diff --git a/app/Presentation/Error/Error4xx/4xx.latte b/app/Presentation/Error/Error4xx/4xx.latte new file mode 100644 index 0000000..49e6127 --- /dev/null +++ b/app/Presentation/Error/Error4xx/4xx.latte @@ -0,0 +1,6 @@ +{block content} +

Oops...

+ +

Your browser sent a request that this server could not understand or process.

+ +

error {$httpCode}

diff --git a/app/Presentation/Error/Error4xx/Error4xxPresenter.php b/app/Presentation/Error/Error4xx/Error4xxPresenter.php new file mode 100644 index 0000000..3418679 --- /dev/null +++ b/app/Presentation/Error/Error4xx/Error4xxPresenter.php @@ -0,0 +1,27 @@ +getCode(); + $file = is_file($file = __DIR__ . "/$code.latte") + ? $file + : __DIR__ . '/4xx.latte'; + $this->template->httpCode = $code; + $this->template->setFile($file); + } +} diff --git a/app/Presentation/Error/Error5xx/500.phtml b/app/Presentation/Error/Error5xx/500.phtml new file mode 100644 index 0000000..a2b900c --- /dev/null +++ b/app/Presentation/Error/Error5xx/500.phtml @@ -0,0 +1,27 @@ + + + +Server Error + + + +
+
+

Server Error

+ +

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

+ +

error 500

+
+
+ + diff --git a/app/Presentation/Error/Error5xx/503.phtml b/app/Presentation/Error/Error5xx/503.phtml new file mode 100644 index 0000000..f123919 --- /dev/null +++ b/app/Presentation/Error/Error5xx/503.phtml @@ -0,0 +1,24 @@ + + + + + + + + +Site is temporarily down for maintenance + +

We're Sorry

+ +

The site is temporarily down for maintenance. Please try again in a few minutes.

diff --git a/app/Presentation/Error/Error5xx/Error5xxPresenter.php b/app/Presentation/Error/Error5xx/Error5xxPresenter.php new file mode 100644 index 0000000..2b16854 --- /dev/null +++ b/app/Presentation/Error/Error5xx/Error5xxPresenter.php @@ -0,0 +1,39 @@ +getParameter('exception'); + $this->logger->log($exception, ILogger::EXCEPTION); + + // Display a generic error message to the user + return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void { + if (preg_match('#^text/html(?:;|$)#', (string) $httpResponse->getHeader('Content-Type'))) { + require __DIR__ . '/500.phtml'; + } + }); + } +} diff --git a/app/Presentation/Home/HomePresenter.php b/app/Presentation/Home/HomePresenter.php new file mode 100644 index 0000000..031d14b --- /dev/null +++ b/app/Presentation/Home/HomePresenter.php @@ -0,0 +1,13 @@ + +
+
+
+ {if $user->identity->twoFactor} +
+ +
+ {else} +
+ +
+ {/if} +
+
+

Dvoufázové ověření (2FA)

+

+ {if $user->identity->twoFactor} + Aktivní a zabezpečeno + {else} + Váš účet je chráněn pouze heslem + {/if} +

+
+
+ +
+ {if $user->identity->twoFactor} + Při každém přihlášení vyžadujeme kód z vaší aplikace. To výrazně zvyšuje bezpečnost vašich dat. + {else} + Doporučujeme aktivaci! Přidáním druhého faktoru ochráníte svůj účet i v případě, že někdo zjistí vaše heslo. + {/if} +
+ +
+ {if $user->identity->twoFactor} + + Vypnout dvoufázové ověření + + {else} + + Nastavit zabezpečení účtu + + {/if} +
+
+ \ No newline at end of file diff --git a/app/Presentation/Setup2fa/Setup2faPresenter.php b/app/Presentation/Setup2fa/Setup2faPresenter.php new file mode 100644 index 0000000..d043302 --- /dev/null +++ b/app/Presentation/Setup2fa/Setup2faPresenter.php @@ -0,0 +1,122 @@ +twoFactorSession = $session->getSection('TwoFactorSetup'); + } + + public function actionDefault(): void + { + /** + * Uživatelská identita = přihlášený user. + * @var UserIdentity + */ + $identity = $this->getUser()->getIdentity(); + + // Pokud už uživatel má 2FA aktivní (příznak v identitě) + if ($identity->twoFactor) { + //$this->flashMessage('Dvoufázové ověření již máte nastaveno.', 'info'); + // Přesměrujte na profil, domovskou stránku, nebo na stránku pro zrušení 2FA + $this->redirect(':Disable2fa:'); + } + } + + public function renderDefault(): void + { + // Načtení secretu ze session + $tempSecret = $this->twoFactorSession->get('tempSecret'); + + // Pokud v session ještě není, vygenerujeme ho + if ($tempSecret === null) { + $tempSecret = $this->twoFactorService->generateSecret(); + $this->twoFactorSession->set('tempSecret', $tempSecret); + } + + /** + * Uživatelská identita = přihlášený user. + * @var UserIdentity + */ + $identity = $this->getUser()->getIdentity(); + + // Vygenerování QR kódu pro šablonu + $this->template->qrCodeUri = $this->twoFactorService->getQrCodeDataUri( + $tempSecret, + $identity->username + ); + + // PŘIDÁNO: Přímý odkaz pro mobilní aplikace + $this->template->otpAuthUri = $this->twoFactorService->getProvisioningUri($tempSecret, $identity->username); + + $this->template->secretKey = $tempSecret; + } + + protected function createComponentVerifyForm(): Form + { + $form = new Form; + $form->addText('code', 'Ověřovací kód:') + ->setRequired('Zadejte prosím 6místný kód z aplikace.') + ->addRule($form::Pattern, 'Kód musí mít 6 číslic', '\d{6}') + ->setHtmlAttribute('placeholder', '000 000') + ->setHtmlAttribute('autocomplete', 'one-time-code'); + + $form->addSubmit('send', 'Aktivovat 2FA'); + + $form->onSuccess[] = $this->verifyFormSucceeded(...); + + return $form; + } + + public function verifyFormSucceeded(Form $form, \stdClass $data): void + { + $secret = $this->twoFactorSession->get('tempSecret'); + + if (!$secret) { + $this->flashMessage('Relace vypršela, zkuste stránku obnovit.', 'error'); + $this->redirect('this'); + } + + if ($this->twoFactorService->verifyCode($secret, $data->code)) { + /** + * Uživatelská identita = přihlášený user. + * @var UserIdentity + */ + $identity = $this->getUser()->getIdentity(); + + // --- LOGIKA ULOŽENÍ DO DB --- + $this->uzivatelFacade->updateTOTPSecret($secret); + + $this->twoFactorSession->remove(); // Po úspěchu smažeme dočasný klíč + + // Aktualizace identity v session + $identity->twoFactor = true; + $identity->totpSecret = $secret; + + $this->flashMessage('Dvoufázové ověření bylo úspěšně nastaveno.', 'success'); + $this->redirect(':Home:'); + } else { + $form->addError('Zadaný kód není správný. Zkontrolujte čas v telefonu.'); + } + } +} \ No newline at end of file diff --git a/app/Presentation/Setup2fa/default.latte b/app/Presentation/Setup2fa/default.latte new file mode 100644 index 0000000..c5669ce --- /dev/null +++ b/app/Presentation/Setup2fa/default.latte @@ -0,0 +1,82 @@ +{block content} + +
+
+
+
+
+

Nastavení dvoufázového ověření (2FA)

+
+ +
+
+ +
+

1. Přidejte si účet do aplikace

+

Použijte Google Authenticator, Authy nebo Microsoft Authenticator.

+ +
+ QR kód +
+ + + +
+ Ruční klíč: + {$secretKey} +
+
+ +
+

2. Ověřte nastavení

+

Zadejte 6místný kód z aplikace pro potvrzení.

+ + + +
+ {form verifyForm} + +
+ {label code class => "form-label" /} + {input code class => "form-control form-control-lg text-center fw-bold", style => "letter-spacing: 0.3rem;", placeholder => "000 000"} +
+
+ {input send class => "btn btn-success btn-lg"} +
+ {/form} +
+
+ +
+
+ + +
+
+
+
+ + + +{/block} \ No newline at end of file diff --git a/app/Presentation/Sign/SignPresenter.php b/app/Presentation/Sign/SignPresenter.php new file mode 100644 index 0000000..e6402bc --- /dev/null +++ b/app/Presentation/Sign/SignPresenter.php @@ -0,0 +1,160 @@ +twoFactorSession = $session->getSection('2fa_auth'); + // $secret = $this->twoFactorService->generateSecret(); + // bdump($secret); + } + + protected function createComponentSignInForm(): Form + { + $form = new Form(); + $form->addText('username', 'Uživatelské jméno:') + ->setRequired('Prosím vyplňte své uživatelské jméno.') + ->setValue(@$_COOKIE['user']); + + $form->addPassword('password', 'Heslo:'); + // setRequired nepoužívat!! kvůli soft logoutu!!! + //->setRequired('Prosím vyplňte své heslo.'); + + $form->addSubmit('send', 'Přihlásit'); + //$form->addProtection(); //ochrana pomocí TOKENu + + $form->onSuccess[] = $this->signInFormSucceeded(...); + return $form; + } + + private function signInFormSucceeded(Form $form, LoginFormData $data): void //moje vlastní třída LoginFormData + { + try { + // 1. Ověříme heslo přes autentifikátor (manuálně bez volání $this->getUser()->login()) + $identity = $this->autentifikator->authenticate($data->username, $data->password); + + // 2. Zjistíme, zda má uživatel aktivní 2FA (např. má v DB uložený secret) + $twoFactor = $identity->twoFactor ?? false; + + if ($twoFactor) { + // Uživatel MÁ 2FA -> uložíme do session a jdeme na druhý krok + $this->twoFactorSession->identity = $identity; + $this->twoFactorSession->setExpiration('5 minutes'); + $this->redirect('twoFactor'); + } else { + // Uživatel NEMÁ 2FA -> přihlásíme ho hned + $this->getUser()->login($identity); + $this->restoreRequest($this->backlink); + $this->redirect(':Home:'); + } + + } catch (Nette\Security\AuthenticationException $e) { + $form->addError('Neplatné jméno nebo heslo.'); + } + // try { + // $this->getUser()->setAuthenticator($this->autentifikator); // musíme ji registrovat! + + // // validace přihlášení je v třídě MujAutentifikator->authenticate(...) + // $this->getUser()->login($data->username, $data->password); + + // // kam potom? + // $this->restoreRequest($this->backlink); // vrátit se na požadovanou stránku + // $this->redirect(':Home:'); // jinak přejdi sem + // } catch (Nette\Database\ConnectionException) { + // error_log("Obvody - neplatne prihlaseni.", 0); //log je ve var/log/apache2/error.log (fail2ban) + // $form->addError('Neplatné přihlášení.'); + // } catch (Nette\Security\AuthenticationException $e) { + // error_log("Obvody - neplatne prihlaseni.", 0); //log je ve var/log/apache2/error.log (fail2ban) + // $form->addError($e->getMessage()); + // } + } + + protected function createComponentTwoFactorForm(): Form + { + $form = new Form(); + $form->addText('code', 'Ověřovací kód (OTP):') + ->setRequired() + ->addRule($form::Pattern, 'Kód musí mít 6 číslic', '\d{6}') + ->setHtmlAttribute('placeholder', '000 000') + ->setHtmlAttribute('autocomplete', 'one-time-code'); + $form->addSubmit('verify', 'Ověřit a přihlásit'); + $form->onSuccess[] = $this->twoFactorFormSucceeded(...); + return $form; + } + + private function twoFactorFormSucceeded(Form $form, \stdClass $data): void + { + /** + * Uživatelská identita = přihlášený user. + * @var UserIdentity + */ + $identity = $this->twoFactorSession->identity; + + if (!$identity) { + $this->redirect('in'); + } + + bdump($identity); + + // Předpokládáme, že secret je uložen v identitě (z DB) + $secret = $identity->totpSecret ?? null; + + if ($this->twoFactorService->verifyCode($secret, $data->code)) { + // KÓD JE SPRÁVNÝ -> Přihlásíme uživatele do Nette nativně + $this->getUser()->login($identity); + + // Vyčistíme dočasnou session + $this->twoFactorSession->remove(); + + $this->restoreRequest($this->backlink); + $this->redirect(':Home:'); + } else { + $form->addError('Neplatný ověřovací kód.'); + } + } + + public function renderTwoFactor(): void + { + if (!$this->twoFactorSession->identity) { + $this->redirect('in'); + } + } + + public function renderIn(): void + { + } + + /** + * Normalní logout. + * @return void + */ + public function actionOut(): void + { + $this->getUser()->logout(); + $this->flashMessage('Odhlášení bylo úspěšné.'); + $this->redirect('Sign:in'); + } +} \ No newline at end of file diff --git a/app/Presentation/Sign/in.latte b/app/Presentation/Sign/in.latte new file mode 100644 index 0000000..5073066 --- /dev/null +++ b/app/Presentation/Sign/in.latte @@ -0,0 +1,22 @@ +{block content} + +{* {control signInForm} *} +
+
+
+
+ {$error} +
+
+ + +
+ +
+ + +
+ +
+
+
diff --git a/app/Presentation/Sign/twoFactor.latte b/app/Presentation/Sign/twoFactor.latte new file mode 100644 index 0000000..5c0f093 --- /dev/null +++ b/app/Presentation/Sign/twoFactor.latte @@ -0,0 +1,72 @@ +{block content} + +
+
+
+
+
+

Dvoufázové ověření

+
+ +
+
+
+ +
+

+ Otevřete svou autentifikační aplikaci a zadejte 6místný kód pro potvrzení identity. +

+
+ +
+ {$flash->message} +
+ + {form twoFactorForm} + +
+ {input code class => "form-control form-control-lg text-center fw-bold", + style => "letter-spacing: 0.4rem; font-size: 2rem;", + placeholder => "· · · · · ·", + autofocus => true} +
+ +
+ {input verify class => "btn btn-primary btn-lg"} +
+ {/form} +
+ + +
+ +

+ Nemáte přístup k zařízení? Kontaktujte podporu. +

+
+
+
+ + \ No newline at end of file diff --git a/assets/main.js b/assets/main.js new file mode 100644 index 0000000..71729d8 --- /dev/null +++ b/assets/main.js @@ -0,0 +1,4 @@ +// Initialize Nette Forms on page load +import netteForms from 'nette-forms'; + +netteForms.initOnLoad(); diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..916192f --- /dev/null +++ b/composer.json @@ -0,0 +1,46 @@ +{ + "name": "nette/web-project", + "description": "Nette: Standard Web Project", + "keywords": ["nette"], + "type": "project", + "license": ["MIT", "BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], + "require": { + "php": ">= 8.2", + "nette/application": "^3.2.3", + "nette/assets": "^1.0.0", + "nette/bootstrap": "^3.2.6", + "nette/caching": "^3.2", + "nette/database": "^3.2", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/http": "^3.3", + "nette/mail": "^4.0", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/utils": "^4.0", + "latte/latte": "^3.1", + "tracy/tracy": "^2.10", + "spomky-labs/otphp": "^11.4", + "endroid/qr-code": "^6.0" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2", + "symfony/thanks": "^1" + }, + "autoload": { + "psr-4": { + "App\\": "app" + } + }, + "scripts": { + "phpstan": "phpstan analyse", + "tester": "tester tests -s" + }, + "minimum-stability": "stable", + "config": { + "allow-plugins": { + "symfony/thanks": true + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..f0d6255 --- /dev/null +++ b/composer.lock @@ -0,0 +1,2172 @@ +{ + "_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": "08ee95b1dc1fc7ee6aa46115e415d4b8", + "packages": [ + { + "name": "bacon/bacon-qr-code", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/36a1cb2b81493fa5b82e50bf8068bf84d1542563", + "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^8.1" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.12", + "phpunit/phpunit": "^10.5.11 || ^11.0.4", + "spatie/phpunit-snapshot-assertions": "^5.1.5", + "spatie/pixelmatch-php": "^1.2.0", + "squizlabs/php_codesniffer": "^3.9" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.3" + }, + "time": "2025-11-19T17:15:36+00:00" + }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "time": "2025-09-16T12:23:56+00:00" + }, + { + "name": "endroid/qr-code", + "version": "6.0.9", + "source": { + "type": "git", + "url": "https://github.com/endroid/qr-code.git", + "reference": "21e888e8597440b2205e2e5c484b6c8e556bcd1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/21e888e8597440b2205e2e5c484b6c8e556bcd1a", + "reference": "21e888e8597440b2205e2e5c484b6c8e556bcd1a", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^3.0", + "php": "^8.2" + }, + "require-dev": { + "endroid/quality": "dev-main", + "ext-gd": "*", + "khanamiryan/qrcode-detector-decoder": "^2.0.2", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "ext-gd": "Enables you to write PNG images", + "khanamiryan/qrcode-detector-decoder": "Enables you to use the image validator", + "roave/security-advisories": "Makes sure package versions with known security issues are not installed", + "setasign/fpdf": "Enables you to use the PDF writer" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/qr-code", + "keywords": [ + "code", + "endroid", + "php", + "qr", + "qrcode" + ], + "support": { + "issues": "https://github.com/endroid/qr-code/issues", + "source": "https://github.com/endroid/qr-code/tree/6.0.9" + }, + "funding": [ + { + "url": "https://github.com/endroid", + "type": "github" + } + ], + "time": "2025-07-13T19:59:45+00:00" + }, + { + "name": "latte/latte", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/nette/latte.git", + "reference": "cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/latte/zipball/cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3", + "reference": "cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "require-dev": { + "nette/php-generator": "^4.0", + "nette/tester": "^2.5", + "nette/utils": "^4.0", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.10" + }, + "suggest": { + "ext-fileinfo": "to use filter |datastream", + "ext-iconv": "to use filters |reverse, |substring", + "ext-intl": "to use Latte\\Engine::setLocale()", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "nette/php-generator": "to use tag {templatePrint}", + "nette/utils": "to use filter |webalize" + }, + "bin": [ + "bin/latte-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Latte\\": "src/Latte" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "homepage": "https://latte.nette.org", + "keywords": [ + "context-sensitive", + "engine", + "escaping", + "html", + "nette", + "security", + "template", + "twig" + ], + "support": { + "issues": "https://github.com/nette/latte/issues", + "source": "https://github.com/nette/latte/tree/v3.1.1" + }, + "time": "2025-12-18T22:30:40+00:00" + }, + { + "name": "nette/application", + "version": "v3.2.9", + "source": { + "type": "git", + "url": "https://github.com/nette/application.git", + "reference": "11d9d6fc53d579a3516c1574c707a5de281bc0a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/application/zipball/11d9d6fc53d579a3516c1574c707a5de281bc0a0", + "reference": "11d9d6fc53d579a3516c1574c707a5de281bc0a0", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.1", + "nette/http": "^3.3.2", + "nette/routing": "^3.1.1", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": "<2.7.1 || >=3.0.0 <3.0.18 || >=3.2", + "nette/caching": "<3.2", + "nette/di": "<3.2", + "nette/forms": "<3.2", + "nette/schema": "<1.3", + "tracy/tracy": "<2.9" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "latte/latte": "^2.10.2 || ^3.0.18", + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Latte in templates", + "nette/forms": "Allows to use Nette\\Application\\UI\\Form" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🏆 Nette Application: a full-stack component-based MVC kernel for PHP that helps you write powerful and modern web applications. Write less, have cleaner code and your work will bring you joy.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "component-based", + "control", + "framework", + "mvc", + "mvp", + "nette", + "presenter", + "routing", + "seo" + ], + "support": { + "issues": "https://github.com/nette/application/issues", + "source": "https://github.com/nette/application/tree/v3.2.9" + }, + "time": "2025-12-19T11:39:00+00:00" + }, + { + "name": "nette/assets", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/nette/assets.git", + "reference": "d747983c8a8ee5e8508ab9b45282c869e6b1f623" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/assets/zipball/d747983c8a8ee5e8508ab9b45282c869e6b1f623", + "reference": "d747983c8a8ee5e8508ab9b45282c869e6b1f623", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/bootstrap": "<3.2.5", + "nette/http": "<3.3.2" + }, + "require-dev": { + "latte/latte": "^3.0.22", + "mockery/mockery": "^1.6@stable", + "nette/application": "^3.2", + "nette/di": "^3.2", + "nette/http": "^3.3.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Assets in templates" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🎨 Nette Assets: elegant asset management for PHP with versioning, caching and mappers for various storage backends.", + "homepage": "https://nette.org", + "keywords": [ + "asset management", + "assets", + "nette", + "resources", + "static files", + "versioning" + ], + "support": { + "issues": "https://github.com/nette/assets/issues", + "source": "https://github.com/nette/assets/tree/v1.0.5" + }, + "time": "2025-11-24T02:49:53+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v3.2.7", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "10fdb1cb05497da39396f2ce1785cea67c8aa439" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/10fdb1cb05497da39396f2ce1785cea67c8aa439", + "reference": "10fdb1cb05497da39396f2ce1785cea67c8aa439", + "shasum": "" + }, + "require": { + "nette/di": "^3.1", + "nette/utils": "^3.2.1 || ^4.0", + "php": "8.0 - 8.5" + }, + "conflict": { + "tracy/tracy": "<2.6" + }, + "require-dev": { + "latte/latte": "^2.8 || ^3.0", + "nette/application": "^3.1", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/robot-loader": "^3.0 || ^4.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.2.7" + }, + "time": "2025-08-01T02:02:03+00:00" + }, + { + "name": "nette/caching", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/nette/caching.git", + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/caching/zipball/a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": "<3.0.12" + }, + "require-dev": { + "latte/latte": "^3.0.12", + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "psr/simple-cache": "^2.0 || ^3.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-pdo_sqlite": "to use SQLiteStorage or SQLiteJournal" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⏱ Nette Caching: library with easy-to-use API and many cache backends.", + "homepage": "https://nette.org", + "keywords": [ + "cache", + "journal", + "memcached", + "nette", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/caching/issues", + "source": "https://github.com/nette/caching/tree/v3.4.0" + }, + "time": "2025-08-06T23:05:08+00:00" + }, + { + "name": "nette/component-model", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/nette/component-model.git", + "reference": "0d100ba05279a1f4b20acecaa617027fbda8ecb2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/component-model/zipball/0d100ba05279a1f4b20acecaa617027fbda8ecb2", + "reference": "0d100ba05279a1f4b20acecaa617027fbda8ecb2", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⚛ Nette Component Model", + "homepage": "https://nette.org", + "keywords": [ + "components", + "nette" + ], + "support": { + "issues": "https://github.com/nette/component-model/issues", + "source": "https://github.com/nette/component-model/tree/v3.1.3" + }, + "time": "2025-11-22T18:56:33+00:00" + }, + { + "name": "nette/database", + "version": "v3.2.8", + "source": { + "type": "git", + "url": "https://github.com/nette/database.git", + "reference": "1a84d3e61aa33461a3d6415235b25a7cd8b3f442" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/database/zipball/1a84d3e61aa33461a3d6415235b25a7cd8b3f442", + "reference": "1a84d3e61aa33461a3d6415235b25a7cd8b3f442", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "nette/caching": "^3.2", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💾 Nette Database: layer with a familiar PDO-like API but much more powerful. Building queries, advanced joins, drivers for MySQL, PostgreSQL, SQLite, MS SQL Server and Oracle.", + "homepage": "https://nette.org", + "keywords": [ + "database", + "mssql", + "mysql", + "nette", + "notorm", + "oracle", + "pdo", + "postgresql", + "queries", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/database/issues", + "source": "https://github.com/nette/database/tree/v3.2.8" + }, + "time": "2025-10-30T22:06:23+00:00" + }, + { + "name": "nette/di", + "version": "v3.2.5", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "5708c328ce7658a73c96b14dd6da7b8b27bf220f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/5708c328ce7658a73c96b14dd6da7b8b27bf220f", + "reference": "5708c328ce7658a73c96b14dd6da7b8b27bf220f", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-tokenizer": "*", + "nette/neon": "^3.3", + "nette/php-generator": "^4.1.6", + "nette/robot-loader": "^4.0", + "nette/schema": "^1.2.5", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.2.5" + }, + "time": "2025-08-14T22:59:46+00:00" + }, + { + "name": "nette/forms", + "version": "v3.2.8", + "source": { + "type": "git", + "url": "https://github.com/nette/forms.git", + "reference": "3bbf691ea0eb50d9594c2109d9252f267092b91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/forms/zipball/3bbf691ea0eb50d9594c2109d9252f267092b91f", + "reference": "3bbf691ea0eb50d9594c2109d9252f267092b91f", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.1", + "nette/http": "^3.3", + "nette/utils": "^4.0.4", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": ">=3.0.0 <3.0.12 || >=3.2" + }, + "require-dev": { + "latte/latte": "^2.10.2 || ^3.0.12", + "nette/application": "^3.0", + "nette/di": "^3.0", + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-intl": "to use date/time controls" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "bootstrap", + "csrf", + "javascript", + "nette", + "validation" + ], + "support": { + "issues": "https://github.com/nette/forms/issues", + "source": "https://github.com/nette/forms/tree/v3.2.8" + }, + "time": "2025-11-22T19:36:34+00:00" + }, + { + "name": "nette/http", + "version": "v3.3.3", + "source": { + "type": "git", + "url": "https://github.com/nette/http.git", + "reference": "c557f21c8cedd621dbfd7990752b1d55ef353f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/http/zipball/c557f21c8cedd621dbfd7990752b1d55ef353f1d", + "reference": "c557f21c8cedd621dbfd7990752b1d55ef353f1d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.4", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/di": "<3.0.3", + "nette/schema": "<1.2" + }, + "require-dev": { + "nette/di": "^3.0", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "ext-fileinfo": "to detect MIME type of uploaded files by Nette\\Http\\FileUpload", + "ext-gd": "to use image function in Nette\\Http\\FileUpload", + "ext-intl": "to support punycode by Nette\\Http\\Url", + "ext-session": "to use Nette\\Http\\Session" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🌐 Nette Http: abstraction for HTTP request, response and session. Provides careful data sanitization and utility for URL and cookies manipulation.", + "homepage": "https://nette.org", + "keywords": [ + "cookies", + "http", + "nette", + "proxy", + "request", + "response", + "security", + "session", + "url" + ], + "support": { + "issues": "https://github.com/nette/http/issues", + "source": "https://github.com/nette/http/tree/v3.3.3" + }, + "time": "2025-10-30T22:32:24+00:00" + }, + { + "name": "nette/mail", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/nette/mail.git", + "reference": "5f16f76ed14a32f34580811d1a07ac357352bbc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/mail/zipball/5f16f76ed14a32f34580811d1a07ac357352bbc4", + "reference": "5f16f76ed14a32f34580811d1a07ac357352bbc4", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "nette/utils": "^4.0", + "php": "8.0 - 8.5" + }, + "require-dev": { + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "ext-fileinfo": "to detect type of attached files", + "ext-openssl": "to use Nette\\Mail\\DkimSigner" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📧 Nette Mail: A handy library for creating and sending emails in PHP.", + "homepage": "https://nette.org", + "keywords": [ + "mail", + "mailer", + "mime", + "nette", + "smtp" + ], + "support": { + "issues": "https://github.com/nette/mail/issues", + "source": "https://github.com/nette/mail/tree/v4.0.4" + }, + "time": "2025-08-01T02:09:42+00:00" + }, + { + "name": "nette/neon", + "version": "v3.4.7", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "cc96bf5264d721d0c102bb976272d3d001a23e65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/cc96bf5264d721d0c102bb976272d3d001a23e65", + "reference": "cc96bf5264d721d0c102bb976272d3d001a23e65", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "8.0 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.7" + }, + "bin": [ + "bin/neon-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "https://neon.nette.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.4.7" + }, + "time": "2026-01-04T08:39:50+00:00" + }, + { + "name": "nette/php-generator", + "version": "v4.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/4707546a1f11badd72f5d82af4f8a6bc64bd56ac", + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/tester": "^2.4", + "nikic/php-parser": "^5.0", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v4.2.0" + }, + "time": "2025-08-06T18:24:31+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v4.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/805fb81376c24755d50bdb8bc69ca4db3def71d1", + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v4.1.0" + }, + "time": "2025-08-06T18:34:21+00:00" + }, + { + "name": "nette/routing", + "version": "v3.1.2", + "source": { + "type": "git", + "url": "https://github.com/nette/routing.git", + "reference": "14c466f3383add0d4f78a82074d3c9841f8edf47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/routing/zipball/14c466f3383add0d4f78a82074d3c9841f8edf47", + "reference": "14c466f3383add0d4f78a82074d3c9841f8edf47", + "shasum": "" + }, + "require": { + "nette/http": "^3.2 || ~4.0.0", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Routing: two-ways URL conversion", + "homepage": "https://nette.org", + "keywords": [ + "nette" + ], + "support": { + "issues": "https://github.com/nette/routing/issues", + "source": "https://github.com/nette/routing/tree/v3.1.2" + }, + "time": "2025-10-31T00:55:27+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.3", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004", + "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.3" + }, + "time": "2025-10-30T22:57:59+00:00" + }, + { + "name": "nette/security", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/security.git", + "reference": "beca6757457281ebc9428743bec7960809f40d49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/security/zipball/beca6757457281ebc9428743bec7960809f40d49", + "reference": "beca6757457281ebc9428743bec7960809f40d49", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/di": "<3.0-stable", + "nette/http": "<3.1.3" + }, + "require-dev": { + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/http": "^3.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔑 Nette Security: provides authentication, authorization and a role-based access control management via ACL (Access Control List)", + "homepage": "https://nette.org", + "keywords": [ + "Authentication", + "acl", + "authorization", + "nette" + ], + "support": { + "issues": "https://github.com/nette/security/issues", + "source": "https://github.com/nette/security/tree/v3.2.2" + }, + "time": "2025-08-01T02:15:08+00:00" + }, + { + "name": "nette/utils", + "version": "v4.1.1", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72", + "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72", + "shasum": "" + }, + "require": { + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.1" + }, + "time": "2025-12-22T12:14:32+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "infection/infection": "^0", + "nikic/php-fuzzer": "^0", + "phpunit/phpunit": "^9|^10|^11", + "vimeo/psalm": "^4|^5|^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2025-09-24T15:06:41+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "spomky-labs/otphp", + "version": "11.4.2", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/otphp.git", + "reference": "2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad", + "reference": "2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^2.0 || ^3.0", + "php": ">=8.1", + "psr/clock": "^1.0", + "symfony/deprecation-contracts": "^3.2" + }, + "require-dev": { + "symfony/error-handler": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "OTPHP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/Spomky-Labs/otphp/contributors" + } + ], + "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator", + "homepage": "https://github.com/Spomky-Labs/otphp", + "keywords": [ + "FreeOTP", + "RFC 4226", + "RFC 6238", + "google authenticator", + "hotp", + "otp", + "totp" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/otphp/issues", + "source": "https://github.com/Spomky-Labs/otphp/tree/11.4.2" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2026-01-23T10:53:01+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "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": "2024-09-25T14:21:43+00:00" + }, + { + "name": "tracy/tracy", + "version": "v2.11.0", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e", + "reference": "eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5 || ^3.0", + "nette/di": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/tester": "^2.2", + "nette/utils": "^3.0 || ^4.0", + "phpstan/phpstan-nette": "^2.0@stable", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.11-dev" + } + }, + "autoload": { + "files": [ + "src/Tracy/functions.php" + ], + "psr-4": { + "Tracy\\": "src" + }, + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "support": { + "issues": "https://github.com/nette/tracy/issues", + "source": "https://github.com/nette/tracy/tree/v2.11.0" + }, + "time": "2025-10-31T00:12:50+00:00" + } + ], + "packages-dev": [ + { + "name": "nette/tester", + "version": "v2.5.7", + "source": { + "type": "git", + "url": "https://github.com/nette/tester.git", + "reference": "dc02e7811f3491a72e87538044586cee2f483d58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tester/zipball/dc02e7811f3491a72e87538044586cee2f483d58", + "reference": "dc02e7811f3491a72e87538044586cee2f483d58", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.5" + }, + "require-dev": { + "ext-simplexml": "*", + "phpstan/phpstan-nette": "^2.0@stable" + }, + "bin": [ + "src/tester" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "Tester\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Miloslav Hůla", + "homepage": "https://github.com/milo" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Tester: enjoyable unit testing in PHP with code coverage reporter. 🍏🍏🍎🍏", + "homepage": "https://tester.nette.org", + "keywords": [ + "Xdebug", + "assertions", + "clover", + "code coverage", + "nette", + "pcov", + "phpdbg", + "phpunit", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/nette/tester/issues", + "source": "https://github.com/nette/tester/tree/v2.5.7" + }, + "time": "2025-11-22T18:50:53+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.33", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f", + "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-12-05T10:24:31+00:00" + }, + { + "name": "phpstan/phpstan-nette", + "version": "2.0.7", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-nette.git", + "reference": "488d326408740b28c364849316ec065c13799568" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-nette/zipball/488d326408740b28c364849316ec065c13799568", + "reference": "488d326408740b28c364849316ec065c13799568", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.12" + }, + "conflict": { + "nette/application": "<2.3.0", + "nette/component-model": "<2.3.0", + "nette/di": "<2.3.0", + "nette/forms": "<2.3.0", + "nette/http": "<2.3.0", + "nette/utils": "<2.3.0" + }, + "require-dev": { + "nette/application": "^3.0", + "nette/di": "^3.0", + "nette/forms": "^3.0", + "nette/utils": "^2.3.0 || ^3.0.0 || ^4.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0.8", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Nette Framework class reflection extension for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-nette/issues", + "source": "https://github.com/phpstan/phpstan-nette/tree/2.0.7" + }, + "time": "2025-12-08T10:39:26+00:00" + }, + { + "name": "symfony/thanks", + "version": "v1.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/thanks.git", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/thanks/zipball/f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": ">=8.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Thanks\\Thanks", + "branch-alias": { + "dev-main": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Thanks\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Encourages sending ⭐ and 💵 to fellow PHP package maintainers (not limited to Symfony components)!", + "support": { + "issues": "https://github.com/symfony/thanks/issues", + "source": "https://github.com/symfony/thanks/tree/v1.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-10-30T17:38:50+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">= 8.2" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/config/common.neon b/config/common.neon new file mode 100644 index 0000000..9e3728a --- /dev/null +++ b/config/common.neon @@ -0,0 +1,35 @@ +# see https://doc.nette.org/en/configuring + +parameters: + + +application: + errorPresenter: + 4xx: Error:Error4xx + 5xx: Error:Error5xx + mapping: App\Presentation\*\**Presenter + + +database: + dsn: 'sqlsrv:server=localhost;Database=auth2fa;TrustServerCertificate=true;LoginTimeout=6;' + user: sa + password: Leviathan8 + + +latte: + strictParsing: yes + extensions: + - App\Presentation\Accessory\LatteExtension + + +assets: + mapping: + default: + path: assets + # type: vite # Uncomment to activate Vite for asset building + + +di: + export: + parameters: no + tags: no diff --git a/config/services.neon b/config/services.neon new file mode 100644 index 0000000..3da313a --- /dev/null +++ b/config/services.neon @@ -0,0 +1,12 @@ +services: + - App\Core\RouterFactory::createRouter + - App\Core\TwoFactorService + - App\Core\MujAutentifikator + +search: + - in: %appDir% + classes: + - *Facade + - *Factory + - *Repository + - *Service diff --git a/latte-lint b/latte-lint new file mode 100644 index 0000000..622a84d --- /dev/null +++ b/latte-lint @@ -0,0 +1,18 @@ +#!/usr/bin/env php +bootConsoleApplication(); +$latte = $container->getByType(Nette\Bridges\ApplicationLatte\TemplateFactory::class) + ->createTemplate() + ->getLatte(); + +$latte->addExtension(new Latte\Tools\LinterExtension); + +$linter = new Latte\Tools\Linter($latte, strict: true); +$ok = $linter->scanDirectory($path); +exit($ok ? 0 : 1); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..5e0b723 --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "type": "module", + "dependencies": { + "nette-forms": "^3.3" + }, + "devDependencies": { + "@nette/vite-plugin": "^1.0.1", + "vite": "^6.3.5" + }, + "scripts": { + "dev": "vite", + "build": "vite build" + } +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..22d3b23 --- /dev/null +++ b/readme.md @@ -0,0 +1,64 @@ +Nette Web Project +================= + +Welcome to the Nette Web Project! This is a basic skeleton application built using +[Nette](https://nette.org), ideal for kick-starting your new web projects. + +Nette is a renowned PHP web development framework, celebrated for its user-friendliness, +robust security, and outstanding performance. It's among the safest choices +for PHP frameworks out there. + +If Nette helps you, consider supporting it by [making a donation](https://nette.org/donate). +Thank you for your generosity! + + +Requirements +------------ + +This Web Project is compatible with Nette 3.2 and requires PHP 8.2. + + +Installation +------------ + +To install the Web Project, Composer is the recommended tool. If you're new to Composer, +follow [these instructions](https://doc.nette.org/composer). Then, run: + + composer create-project nette/web-project path/to/install + cd path/to/install + +Ensure the `temp/` and `log/` directories are writable. + + +Asset Building with Vite +------------------------ + +This project supports Vite for asset building, which is recommended but optional. To activate Vite: + +1. Uncomment the `type: vite` line in the `common.neon` configuration file under the assets mapping section. +2. Then set up and build the assets: + + npm install + npm run build + + +Web Server Setup +---------------- + +To quickly dive in, use PHP's built-in server: + + php -S localhost:8000 -t www + +Then, open `http://localhost:8000` in your browser to view the welcome page. + +For Apache or Nginx users, configure a virtual host pointing to your project's `www/` directory. + +**Important Note:** Ensure `app/`, `config/`, `log/`, and `temp/` directories are not web-accessible. +Refer to [security warning](https://nette.org/security-warning) for more details. + + +Minimal Skeleton +---------------- + +For demonstrating issues or similar tasks, rather than starting a new project, use +[minimal skeleton](https://github.com/nette/web-project/tree/minimal). diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..fe5f751 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,25 @@ +writeFile('Hello World!', 'qrcode.png'); +``` + +## Available image renderer back ends +BaconQrCode comes with multiple back ends for rendering images. Currently included are the following: + +- `ImagickImageBackEnd`: renders raster images using the Imagick library +- `SvgImageBackEnd`: renders SVG files using XMLWriter +- `EpsImageBackEnd`: renders EPS files + +### GDLib Renderer +GD library has so many limitations, that GD support is not added as backend, but as separated renderer. +Use `GDLibRenderer` instead of `ImageRenderer`. These are the limitations: + +- Does not support gradient. +- Does not support any curves, so you QR code is always squared. + +Example usage: + +```php +use BaconQrCode\Renderer\GDLibRenderer; +use BaconQrCode\Writer; + +$renderer = new GDLibRenderer(400); +$writer = new Writer($renderer); +$writer->writeFile('Hello World!', 'qrcode.png'); +``` + +## Development + +To run unit tests, you need to have [Node.js](https://nodejs.org/en) and the pixelmatch library installed. Running +`npm install` will install this for you. diff --git a/vendor/bacon/bacon-qr-code/composer.json b/vendor/bacon/bacon-qr-code/composer.json new file mode 100644 index 0000000..37e8c75 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/composer.json @@ -0,0 +1,51 @@ +{ + "name": "bacon/bacon-qr-code", + "description": "BaconQrCode is a QR code generator for PHP.", + "license": "BSD-2-Clause", + "homepage": "https://github.com/Bacon/BaconQrCode", + "require": { + "php": "^8.1", + "ext-iconv": "*", + "dasprid/enum": "^1.0.3" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "BaconQrCodeTest\\": "test/" + } + }, + "require-dev": { + "phpunit/phpunit": "^10.5.11 || ^11.0.4", + "spatie/phpunit-snapshot-assertions": "^5.1.5", + "spatie/pixelmatch-php": "^1.2.0", + "squizlabs/php_codesniffer": "^3.9", + "phly/keep-a-changelog": "^2.12" + }, + "config": { + "allow-plugins": { + "ocramius/package-versions": true, + "php-http/discovery": true + } + }, + "archive": { + "exclude": [ + "/test", + "/phpunit.xml.dist" + ] + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/BitArray.php b/vendor/bacon/bacon-qr-code/src/Common/BitArray.php new file mode 100644 index 0000000..9ec8629 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/BitArray.php @@ -0,0 +1,364 @@ + + */ + private SplFixedArray $bits; + + /** + * Creates a new bit array with a given size. + */ + public function __construct(private int $size = 0) + { + $this->bits = SplFixedArray::fromArray(array_fill(0, ($this->size + 31) >> 3, 0)); + } + + /** + * Gets the size in bits. + */ + public function getSize() : int + { + return $this->size; + } + + /** + * Gets the size in bytes. + */ + public function getSizeInBytes() : int + { + return ($this->size + 7) >> 3; + } + + /** + * Ensures that the array has a minimum capacity. + */ + public function ensureCapacity(int $size) : void + { + if ($size > count($this->bits) << 5) { + $this->bits->setSize(($size + 31) >> 5); + } + } + + /** + * Gets a specific bit. + */ + public function get(int $i) : bool + { + return 0 !== ($this->bits[$i >> 5] & (1 << ($i & 0x1f))); + } + + /** + * Sets a specific bit. + */ + public function set(int $i) : void + { + $this->bits[$i >> 5] = $this->bits[$i >> 5] | 1 << ($i & 0x1f); + } + + /** + * Flips a specific bit. + */ + public function flip(int $i) : void + { + $this->bits[$i >> 5] ^= 1 << ($i & 0x1f); + } + + /** + * Gets the next set bit position from a given position. + */ + public function getNextSet(int $from) : int + { + if ($from >= $this->size) { + return $this->size; + } + + $bitsOffset = $from >> 5; + $currentBits = $this->bits[$bitsOffset]; + $bitsLength = count($this->bits); + $currentBits &= ~((1 << ($from & 0x1f)) - 1); + + while (0 === $currentBits) { + if (++$bitsOffset === $bitsLength) { + return $this->size; + } + + $currentBits = $this->bits[$bitsOffset]; + } + + $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits); + return min($result, $this->size); + } + + /** + * Gets the next unset bit position from a given position. + */ + public function getNextUnset(int $from) : int + { + if ($from >= $this->size) { + return $this->size; + } + + $bitsOffset = $from >> 5; + $currentBits = ~$this->bits[$bitsOffset]; + $bitsLength = count($this->bits); + $currentBits &= ~((1 << ($from & 0x1f)) - 1); + + while (0 === $currentBits) { + if (++$bitsOffset === $bitsLength) { + return $this->size; + } + + $currentBits = ~$this->bits[$bitsOffset]; + } + + $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits); + return min($result, $this->size); + } + + /** + * Sets a bulk of bits. + */ + public function setBulk(int $i, int $newBits) : void + { + $this->bits[$i >> 5] = $newBits; + } + + /** + * Sets a range of bits. + * + * @throws InvalidArgumentException if end is smaller than start + */ + public function setRange(int $start, int $end) : void + { + if ($end < $start) { + throw new InvalidArgumentException('End must be greater or equal to start'); + } + + if ($end === $start) { + return; + } + + --$end; + + $firstInt = $start >> 5; + $lastInt = $end >> 5; + + for ($i = $firstInt; $i <= $lastInt; ++$i) { + $firstBit = $i > $firstInt ? 0 : $start & 0x1f; + $lastBit = $i < $lastInt ? 31 : $end & 0x1f; + + if (0 === $firstBit && 31 === $lastBit) { + $mask = 0x7fffffff; + } else { + $mask = 0; + + for ($j = $firstBit; $j < $lastBit; ++$j) { + $mask |= 1 << $j; + } + } + + $this->bits[$i] = $this->bits[$i] | $mask; + } + } + + /** + * Clears the bit array, unsetting every bit. + */ + public function clear() : void + { + $bitsLength = count($this->bits); + + for ($i = 0; $i < $bitsLength; ++$i) { + $this->bits[$i] = 0; + } + } + + /** + * Checks if a range of bits is set or not set. + + * @throws InvalidArgumentException if end is smaller than start + */ + public function isRange(int $start, int $end, bool $value) : bool + { + if ($end < $start) { + throw new InvalidArgumentException('End must be greater or equal to start'); + } + + if ($end === $start) { + return true; + } + + --$end; + + $firstInt = $start >> 5; + $lastInt = $end >> 5; + + for ($i = $firstInt; $i <= $lastInt; ++$i) { + $firstBit = $i > $firstInt ? 0 : $start & 0x1f; + $lastBit = $i < $lastInt ? 31 : $end & 0x1f; + + if (0 === $firstBit && 31 === $lastBit) { + $mask = 0x7fffffff; + } else { + $mask = 0; + + for ($j = $firstBit; $j <= $lastBit; ++$j) { + $mask |= 1 << $j; + } + } + + if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) { + return false; + } + } + + return true; + } + + /** + * Appends a bit to the array. + */ + public function appendBit(bool $bit) : void + { + $this->ensureCapacity($this->size + 1); + + if ($bit) { + $this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f)); + } + + ++$this->size; + } + + /** + * Appends a number of bits (up to 32) to the array. + + * @throws InvalidArgumentException if num bits is not between 0 and 32 + */ + public function appendBits(int $value, int $numBits) : void + { + if ($numBits < 0 || $numBits > 32) { + throw new InvalidArgumentException('Num bits must be between 0 and 32'); + } + + $this->ensureCapacity($this->size + $numBits); + + for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) { + $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1); + } + } + + /** + * Appends another bit array to this array. + */ + public function appendBitArray(self $other) : void + { + $otherSize = $other->getSize(); + $this->ensureCapacity($this->size + $other->getSize()); + + for ($i = 0; $i < $otherSize; ++$i) { + $this->appendBit($other->get($i)); + } + } + + /** + * Makes an exclusive-or comparision on the current bit array. + * + * @throws InvalidArgumentException if sizes don't match + */ + public function xorBits(self $other) : void + { + $bitsLength = count($this->bits); + $otherBits = $other->getBitArray(); + + if ($bitsLength !== count($otherBits)) { + throw new InvalidArgumentException('Sizes don\'t match'); + } + + for ($i = 0; $i < $bitsLength; ++$i) { + $this->bits[$i] = $this->bits[$i] ^ $otherBits[$i]; + } + } + + /** + * Converts the bit array to a byte array. + * + * @return SplFixedArray + */ + public function toBytes(int $bitOffset, int $numBytes) : SplFixedArray + { + $bytes = new SplFixedArray($numBytes); + + for ($i = 0; $i < $numBytes; ++$i) { + $byte = 0; + + for ($j = 0; $j < 8; ++$j) { + if ($this->get($bitOffset)) { + $byte |= 1 << (7 - $j); + } + + ++$bitOffset; + } + + $bytes[$i] = $byte; + } + + return $bytes; + } + + /** + * Gets the internal bit array. + * + * @return SplFixedArray + */ + public function getBitArray() : SplFixedArray + { + return $this->bits; + } + + /** + * Reverses the array. + */ + public function reverse() : void + { + $newBits = new SplFixedArray(count($this->bits)); + + for ($i = 0; $i < $this->size; ++$i) { + if ($this->get($this->size - $i - 1)) { + $newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f)); + } + } + + $this->bits = $newBits; + } + + /** + * Returns a string representation of the bit array. + */ + public function __toString() : string + { + $result = ''; + + for ($i = 0; $i < $this->size; ++$i) { + if (0 === ($i & 0x07)) { + $result .= ' '; + } + + $result .= $this->get($i) ? 'X' : '.'; + } + + return $result; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php b/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php new file mode 100644 index 0000000..294afb4 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/BitMatrix.php @@ -0,0 +1,307 @@ + + */ + private SplFixedArray $bits; + + /** + * @throws InvalidArgumentException if a dimension is smaller than zero + */ + public function __construct(int $width, ?int $height = null) + { + if (null === $height) { + $height = $width; + } + + if ($width < 1 || $height < 1) { + throw new InvalidArgumentException('Both dimensions must be greater than zero'); + } + + $this->width = $width; + $this->height = $height; + $this->rowSize = ($width + 31) >> 5; + $this->bits = SplFixedArray::fromArray(array_fill(0, $this->rowSize * $height, 0)); + } + + /** + * Gets the requested bit, where true means black. + */ + public function get(int $x, int $y) : bool + { + $offset = $y * $this->rowSize + ($x >> 5); + return 0 !== (BitUtils::unsignedRightShift($this->bits[$offset], ($x & 0x1f)) & 1); + } + + /** + * Sets the given bit to true. + */ + public function set(int $x, int $y) : void + { + $offset = $y * $this->rowSize + ($x >> 5); + $this->bits[$offset] = $this->bits[$offset] | (1 << ($x & 0x1f)); + } + + /** + * Flips the given bit. + */ + public function flip(int $x, int $y) : void + { + $offset = $y * $this->rowSize + ($x >> 5); + $this->bits[$offset] = $this->bits[$offset] ^ (1 << ($x & 0x1f)); + } + + /** + * Clears all bits (set to false). + */ + public function clear() : void + { + $max = count($this->bits); + + for ($i = 0; $i < $max; ++$i) { + $this->bits[$i] = 0; + } + } + + /** + * Sets a square region of the bit matrix to true. + * + * @throws InvalidArgumentException if left or top are negative + * @throws InvalidArgumentException if width or height are smaller than 1 + * @throws InvalidArgumentException if region does not fit into the matix + */ + public function setRegion(int $left, int $top, int $width, int $height) : void + { + if ($top < 0 || $left < 0) { + throw new InvalidArgumentException('Left and top must be non-negative'); + } + + if ($height < 1 || $width < 1) { + throw new InvalidArgumentException('Width and height must be at least 1'); + } + + $right = $left + $width; + $bottom = $top + $height; + + if ($bottom > $this->height || $right > $this->width) { + throw new InvalidArgumentException('The region must fit inside the matrix'); + } + + for ($y = $top; $y < $bottom; ++$y) { + $offset = $y * $this->rowSize; + + for ($x = $left; $x < $right; ++$x) { + $index = $offset + ($x >> 5); + $this->bits[$index] = $this->bits[$index] | (1 << ($x & 0x1f)); + } + } + } + + /** + * A fast method to retrieve one row of data from the matrix as a BitArray. + */ + public function getRow(int $y, ?BitArray $row = null) : BitArray + { + if (null === $row || $row->getSize() < $this->width) { + $row = new BitArray($this->width); + } + + $offset = $y * $this->rowSize; + + for ($x = 0; $x < $this->rowSize; ++$x) { + $row->setBulk($x << 5, $this->bits[$offset + $x]); + } + + return $row; + } + + /** + * Sets a row of data from a BitArray. + */ + public function setRow(int $y, BitArray $row) : void + { + $bits = $row->getBitArray(); + + for ($i = 0; $i < $this->rowSize; ++$i) { + $this->bits[$y * $this->rowSize + $i] = $bits[$i]; + } + } + + /** + * This is useful in detecting the enclosing rectangle of a 'pure' barcode. + * + * @return int[]|null + */ + public function getEnclosingRectangle() : ?array + { + $left = $this->width; + $top = $this->height; + $right = -1; + $bottom = -1; + + for ($y = 0; $y < $this->height; ++$y) { + for ($x32 = 0; $x32 < $this->rowSize; ++$x32) { + $bits = $this->bits[$y * $this->rowSize + $x32]; + + if (0 !== $bits) { + if ($y < $top) { + $top = $y; + } + + if ($y > $bottom) { + $bottom = $y; + } + + if ($x32 * 32 < $left) { + $bit = 0; + + while (($bits << (31 - $bit)) === 0) { + $bit++; + } + + if (($x32 * 32 + $bit) < $left) { + $left = $x32 * 32 + $bit; + } + } + } + + if ($x32 * 32 + 31 > $right) { + $bit = 31; + + while (0 === BitUtils::unsignedRightShift($bits, $bit)) { + --$bit; + } + + if (($x32 * 32 + $bit) > $right) { + $right = $x32 * 32 + $bit; + } + } + } + } + + $width = $right - $left; + $height = $bottom - $top; + + if ($width < 0 || $height < 0) { + return null; + } + + return [$left, $top, $width, $height]; + } + + /** + * Gets the most top left set bit. + * + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return int[]|null + */ + public function getTopLeftOnBit() : ?array + { + $bitsOffset = 0; + + while ($bitsOffset < count($this->bits) && 0 === $this->bits[$bitsOffset]) { + ++$bitsOffset; + } + + if (count($this->bits) === $bitsOffset) { + return null; + } + + $x = intdiv($bitsOffset, $this->rowSize); + $y = ($bitsOffset % $this->rowSize) << 5; + + $bits = $this->bits[$bitsOffset]; + $bit = 0; + + while (0 === ($bits << (31 - $bit))) { + ++$bit; + } + + $x += $bit; + + return [$x, $y]; + } + + /** + * Gets the most bottom right set bit. + * + * This is useful in detecting a corner of a 'pure' barcode. + * + * @return int[]|null + */ + public function getBottomRightOnBit() : ?array + { + $bitsOffset = count($this->bits) - 1; + + while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) { + --$bitsOffset; + } + + if ($bitsOffset < 0) { + return null; + } + + $x = intdiv($bitsOffset, $this->rowSize); + $y = ($bitsOffset % $this->rowSize) << 5; + + $bits = $this->bits[$bitsOffset]; + $bit = 0; + + while (0 === BitUtils::unsignedRightShift($bits, $bit)) { + --$bit; + } + + $x += $bit; + + return [$x, $y]; + } + + /** + * Gets the width of the matrix, + */ + public function getWidth() : int + { + return $this->width; + } + + /** + * Gets the height of the matrix. + */ + public function getHeight() : int + { + return $this->height; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php b/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php new file mode 100644 index 0000000..0c575b4 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/BitUtils.php @@ -0,0 +1,41 @@ +>>" in other + * languages. + */ + public static function unsignedRightShift(int $a, int $b) : int + { + return ( + $a >= 0 + ? $a >> $b + : (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1)) + ); + } + + /** + * Gets the number of trailing zeros. + */ + public static function numberOfTrailingZeros(int $i) : int + { + $lastPos = strrpos(str_pad(decbin($i), 32, '0', STR_PAD_LEFT), '1'); + return $lastPos === false ? 32 : 31 - $lastPos; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php b/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php new file mode 100644 index 0000000..8b62b8c --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/CharacterSetEci.php @@ -0,0 +1,177 @@ +|null + */ + private static ?array $valueToEci; + + /** + * @var array|null + */ + private static ?array $nameToEci = null; + + /** + * @param int[] $values + */ + public function __construct(private readonly array $values, string ...$otherEncodingNames) + { + $this->otherEncodingNames = $otherEncodingNames; + } + + /** + * Returns the primary value. + */ + public function getValue() : int + { + return $this->values[0]; + } + + /** + * Gets character set ECI by value. + * + * Returns the representing ECI of a given value, or null if it is legal but unsupported. + * + * @throws InvalidArgumentException if value is not between 0 and 900 + */ + public static function getCharacterSetEciByValue(int $value) : ?self + { + if ($value < 0 || $value >= 900) { + throw new InvalidArgumentException('Value must be between 0 and 900'); + } + + $valueToEci = self::valueToEci(); + + if (! array_key_exists($value, $valueToEci)) { + return null; + } + + return $valueToEci[$value]; + } + + /** + * Returns character set ECI by name. + * + * Returns the representing ECI of a given name, or null if it is legal but unsupported + */ + public static function getCharacterSetEciByName(string $name) : ?self + { + $nameToEci = self::nameToEci(); + $name = strtolower($name); + + if (! array_key_exists($name, $nameToEci)) { + return null; + } + + return $nameToEci[$name]; + } + + private static function valueToEci() : array + { + if (null !== self::$valueToEci) { + return self::$valueToEci; + } + + self::$valueToEci = []; + + foreach (self::values() as $eci) { + foreach ($eci->values as $value) { + self::$valueToEci[$value] = $eci; + } + } + + return self::$valueToEci; + } + + private static function nameToEci() : array + { + if (null !== self::$nameToEci) { + return self::$nameToEci; + } + + self::$nameToEci = []; + + foreach (self::values() as $eci) { + self::$nameToEci[strtolower($eci->name())] = $eci; + + foreach ($eci->otherEncodingNames as $name) { + self::$nameToEci[strtolower($name)] = $eci; + } + } + + return self::$nameToEci; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php b/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php new file mode 100644 index 0000000..bc9e865 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/EcBlock.php @@ -0,0 +1,33 @@ +count; + } + + /** + * Returns the number of data codewords. + */ + public function getDataCodewords() : int + { + return $this->dataCodewords; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php b/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php new file mode 100644 index 0000000..63c52a9 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/EcBlocks.php @@ -0,0 +1,66 @@ +ecBlocks = $ecBlocks; + } + + /** + * Returns the number of EC codewords per block. + */ + public function getEcCodewordsPerBlock() : int + { + return $this->ecCodewordsPerBlock; + } + + /** + * Returns the total number of EC block appearances. + */ + public function getNumBlocks() : int + { + $total = 0; + + foreach ($this->ecBlocks as $ecBlock) { + $total += $ecBlock->getCount(); + } + + return $total; + } + + /** + * Returns the total count of EC codewords. + */ + public function getTotalEcCodewords() : int + { + return $this->ecCodewordsPerBlock * $this->getNumBlocks(); + } + + /** + * Returns the EC blocks included in this collection. + * + * @return EcBlock[] + */ + public function getEcBlocks() : array + { + return $this->ecBlocks; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php b/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php new file mode 100644 index 0000000..ac84d66 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/ErrorCorrectionLevel.php @@ -0,0 +1,57 @@ +bits; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php b/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php new file mode 100644 index 0000000..6a5da0b --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/FormatInformation.php @@ -0,0 +1,196 @@ +ecLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x3); + $this->dataMask = $formatInfo & 0x7; + } + + /** + * Checks how many bits are different between two integers. + */ + public static function numBitsDiffering(int $a, int $b) : int + { + $a ^= $b; + + return ( + self::BITS_SET_IN_HALF_BYTE[$a & 0xf] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 4) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 8) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 12) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 16) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 20) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 24) & 0xf)] + + self::BITS_SET_IN_HALF_BYTE[(BitUtils::unsignedRightShift($a, 28) & 0xf)] + ); + } + + /** + * Decodes format information. + */ + public static function decodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self + { + $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2); + + if (null !== $formatInfo) { + return $formatInfo; + } + + // Should return null, but, some QR codes apparently do not mask this info. Try again by actually masking the + // pattern first. + return self::doDecodeFormatInformation( + $maskedFormatInfo1 ^ self::FORMAT_INFO_MASK_QR, + $maskedFormatInfo2 ^ self::FORMAT_INFO_MASK_QR + ); + } + + /** + * Internal method for decoding format information. + */ + private static function doDecodeFormatInformation(int $maskedFormatInfo1, int $maskedFormatInfo2) : ?self + { + $bestDifference = PHP_INT_MAX; + $bestFormatInfo = 0; + + foreach (self::FORMAT_INFO_DECODE_LOOKUP as $decodeInfo) { + $targetInfo = $decodeInfo[0]; + + if ($targetInfo === $maskedFormatInfo1 || $targetInfo === $maskedFormatInfo2) { + // Found an exact match + return new self($decodeInfo[1]); + } + + $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo); + + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + + if ($maskedFormatInfo1 !== $maskedFormatInfo2) { + // Also try the other option + $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo); + + if ($bitsDifference < $bestDifference) { + $bestFormatInfo = $decodeInfo[1]; + $bestDifference = $bitsDifference; + } + } + } + + // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match. + if ($bestDifference <= 3) { + return new self($bestFormatInfo); + } + + return null; + } + + /** + * Returns the error correction level. + */ + public function getErrorCorrectionLevel() : ErrorCorrectionLevel + { + return $this->ecLevel; + } + + /** + * Returns the data mask. + */ + public function getDataMask() : int + { + return $this->dataMask; + } + + /** + * Hashes the code of the EC level. + */ + public function hashCode() : int + { + return ($this->ecLevel->getBits() << 3) | $this->dataMask; + } + + /** + * Verifies if this instance equals another one. + */ + public function equals(self $other) : bool + { + return ( + $this->ecLevel === $other->ecLevel + && $this->dataMask === $other->dataMask + ); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/Mode.php b/vendor/bacon/bacon-qr-code/src/Common/Mode.php new file mode 100644 index 0000000..f5fb153 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/Mode.php @@ -0,0 +1,69 @@ +getVersionNumber(); + + if ($number <= 9) { + $offset = 0; + } elseif ($number <= 26) { + $offset = 1; + } else { + $offset = 2; + } + + return $this->characterCountBitsForVersions[$offset]; + } + + /** + * Returns the four bits used to encode this mode. + */ + public function getBits() : int + { + return $this->bits; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php b/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php new file mode 100644 index 0000000..d16a75e --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/ReedSolomonCodec.php @@ -0,0 +1,454 @@ + 8) { + throw new InvalidArgumentException('Symbol size must be between 0 and 8'); + } + + if ($firstRoot < 0 || $firstRoot >= (1 << $symbolSize)) { + throw new InvalidArgumentException('First root must be between 0 and ' . (1 << $symbolSize)); + } + + if ($numRoots < 0 || $numRoots >= (1 << $symbolSize)) { + throw new InvalidArgumentException('Num roots must be between 0 and ' . (1 << $symbolSize)); + } + + if ($padding < 0 || $padding >= ((1 << $symbolSize) - 1 - $numRoots)) { + throw new InvalidArgumentException( + 'Padding must be between 0 and ' . ((1 << $symbolSize) - 1 - $numRoots) + ); + } + + $this->symbolSize = $symbolSize; + $this->blockSize = (1 << $symbolSize) - 1; + $this->padding = $padding; + $this->alphaTo = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false); + $this->indexOf = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false); + + // Generate galous field lookup table + $this->indexOf[0] = $this->blockSize; + $this->alphaTo[$this->blockSize] = 0; + + $sr = 1; + + for ($i = 0; $i < $this->blockSize; ++$i) { + $this->indexOf[$sr] = $i; + $this->alphaTo[$i] = $sr; + + $sr <<= 1; + + if ($sr & (1 << $symbolSize)) { + $sr ^= $gfPoly; + } + + $sr &= $this->blockSize; + } + + if (1 !== $sr) { + throw new RuntimeException('Field generator polynomial is not primitive'); + } + + // Form RS code generator polynomial from its roots + $this->generatorPoly = SplFixedArray::fromArray(array_fill(0, $numRoots + 1, 0), false); + $this->firstRoot = $firstRoot; + $this->primitive = $primitive; + $this->numRoots = $numRoots; + + // Find prim-th root of 1, used in decoding + for ($iPrimitive = 1; ($iPrimitive % $primitive) !== 0; $iPrimitive += $this->blockSize) { + } + + $this->iPrimitive = intdiv($iPrimitive, $primitive); + + $this->generatorPoly[0] = 1; + + for ($i = 0, $root = $firstRoot * $primitive; $i < $numRoots; ++$i, $root += $primitive) { + $this->generatorPoly[$i + 1] = 1; + + for ($j = $i; $j > 0; $j--) { + if ($this->generatorPoly[$j] !== 0) { + $this->generatorPoly[$j] = $this->generatorPoly[$j - 1] ^ $this->alphaTo[ + $this->modNn($this->indexOf[$this->generatorPoly[$j]] + $root) + ]; + } else { + $this->generatorPoly[$j] = $this->generatorPoly[$j - 1]; + } + } + + $this->generatorPoly[$j] = $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[0]] + $root)]; + } + + // Convert generator poly to index form for quicker encoding + for ($i = 0; $i <= $numRoots; ++$i) { + $this->generatorPoly[$i] = $this->indexOf[$this->generatorPoly[$i]]; + } + } + + /** + * Encodes data and writes result back into parity array. + */ + public function encode(SplFixedArray $data, SplFixedArray $parity) : void + { + for ($i = 0; $i < $this->numRoots; ++$i) { + $parity[$i] = 0; + } + + $iterations = $this->blockSize - $this->numRoots - $this->padding; + + for ($i = 0; $i < $iterations; ++$i) { + $feedback = $this->indexOf[$data[$i] ^ $parity[0]]; + + if ($feedback !== $this->blockSize) { + // Feedback term is non-zero + $feedback = $this->modNn($this->blockSize - $this->generatorPoly[$this->numRoots] + $feedback); + + for ($j = 1; $j < $this->numRoots; ++$j) { + $parity[$j] = $parity[$j] ^ $this->alphaTo[ + $this->modNn($feedback + $this->generatorPoly[$this->numRoots - $j]) + ]; + } + } + + for ($j = 0; $j < $this->numRoots - 1; ++$j) { + $parity[$j] = $parity[$j + 1]; + } + + if ($feedback !== $this->blockSize) { + $parity[$this->numRoots - 1] = $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[0])]; + } else { + $parity[$this->numRoots - 1] = 0; + } + } + } + + /** + * Decodes received data. + */ + public function decode(SplFixedArray $data, ?SplFixedArray $erasures = null) : ?int + { + // This speeds up the initialization a bit. + $numRootsPlusOne = SplFixedArray::fromArray(array_fill(0, $this->numRoots + 1, 0), false); + $numRoots = SplFixedArray::fromArray(array_fill(0, $this->numRoots, 0), false); + + $lambda = clone $numRootsPlusOne; + $b = clone $numRootsPlusOne; + $t = clone $numRootsPlusOne; + $omega = clone $numRootsPlusOne; + $root = clone $numRoots; + $loc = clone $numRoots; + + $numErasures = (null !== $erasures ? count($erasures) : 0); + + // Form the Syndromes; i.e., evaluate data(x) at roots of g(x) + $syndromes = SplFixedArray::fromArray(array_fill(0, $this->numRoots, $data[0]), false); + + for ($i = 1; $i < $this->blockSize - $this->padding; ++$i) { + for ($j = 0; $j < $this->numRoots; ++$j) { + if ($syndromes[$j] === 0) { + $syndromes[$j] = $data[$i]; + } else { + $syndromes[$j] = $data[$i] ^ $this->alphaTo[ + $this->modNn($this->indexOf[$syndromes[$j]] + ($this->firstRoot + $j) * $this->primitive) + ]; + } + } + } + + // Convert syndromes to index form, checking for nonzero conditions + $syndromeError = 0; + + for ($i = 0; $i < $this->numRoots; ++$i) { + $syndromeError |= $syndromes[$i]; + $syndromes[$i] = $this->indexOf[$syndromes[$i]]; + } + + if (! $syndromeError) { + // If syndrome is zero, data[] is a codeword and there are no errors to correct, so return data[] + // unmodified. + return 0; + } + + $lambda[0] = 1; + + if ($numErasures > 0) { + // Init lambda to be the erasure locator polynomial + $lambda[1] = $this->alphaTo[$this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[0]))]; + + for ($i = 1; $i < $numErasures; ++$i) { + $u = $this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[$i])); + + for ($j = $i + 1; $j > 0; --$j) { + $tmp = $this->indexOf[$lambda[$j - 1]]; + + if ($tmp !== $this->blockSize) { + $lambda[$j] = $lambda[$j] ^ $this->alphaTo[$this->modNn($u + $tmp)]; + } + } + } + } + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $b[$i] = $this->indexOf[$lambda[$i]]; + } + + // Begin Berlekamp-Massey algorithm to determine error+erasure locator polynomial + $r = $numErasures; + $el = $numErasures; + + while (++$r <= $this->numRoots) { + // Compute discrepancy at the r-th step in poly form + $discrepancyR = 0; + + for ($i = 0; $i < $r; ++$i) { + if ($lambda[$i] !== 0 && $syndromes[$r - $i - 1] !== $this->blockSize) { + $discrepancyR ^= $this->alphaTo[ + $this->modNn($this->indexOf[$lambda[$i]] + $syndromes[$r - $i - 1]) + ]; + } + } + + $discrepancyR = $this->indexOf[$discrepancyR]; + + if ($discrepancyR === $this->blockSize) { + $tmp = $b->toArray(); + array_unshift($tmp, $this->blockSize); + array_pop($tmp); + $b = SplFixedArray::fromArray($tmp, false); + continue; + } + + $t[0] = $lambda[0]; + + for ($i = 0; $i < $this->numRoots; ++$i) { + if ($b[$i] !== $this->blockSize) { + $t[$i + 1] = $lambda[$i + 1] ^ $this->alphaTo[$this->modNn($discrepancyR + $b[$i])]; + } else { + $t[$i + 1] = $lambda[$i + 1]; + } + } + + if (2 * $el <= $r + $numErasures - 1) { + $el = $r + $numErasures - $el; + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $b[$i] = ( + $lambda[$i] === 0 + ? $this->blockSize + : $this->modNn($this->indexOf[$lambda[$i]] - $discrepancyR + $this->blockSize) + ); + } + } else { + $tmp = $b->toArray(); + array_unshift($tmp, $this->blockSize); + array_pop($tmp); + $b = SplFixedArray::fromArray($tmp, false); + } + + $lambda = clone $t; + } + + // Convert lambda to index form and compute deg(lambda(x)) + $degLambda = 0; + + for ($i = 0; $i <= $this->numRoots; ++$i) { + $lambda[$i] = $this->indexOf[$lambda[$i]]; + + if ($lambda[$i] !== $this->blockSize) { + $degLambda = $i; + } + } + + // Find roots of the error+erasure locator polynomial by Chien search. + $reg = clone $lambda; + $reg[0] = 0; + $count = 0; + $i = 1; + + for ($k = $this->iPrimitive - 1; $i <= $this->blockSize; ++$i, $k = $this->modNn($k + $this->iPrimitive)) { + $q = 1; + + for ($j = $degLambda; $j > 0; $j--) { + if ($reg[$j] !== $this->blockSize) { + $reg[$j] = $this->modNn($reg[$j] + $j); + $q ^= $this->alphaTo[$reg[$j]]; + } + } + + if ($q !== 0) { + // Not a root + continue; + } + + // Store root (index-form) and error location number + $root[$count] = $i; + $loc[$count] = $k; + + if (++$count === $degLambda) { + break; + } + } + + if ($degLambda !== $count) { + // deg(lambda) unequal to number of roots: uncorrectable error detected + return null; + } + + // Compute err+eras evaluate poly omega(x) = s(x)*lambda(x) (modulo x**numRoots). In index form. Also find + // deg(omega). + $degOmega = $degLambda - 1; + + for ($i = 0; $i <= $degOmega; ++$i) { + $tmp = 0; + + for ($j = $i; $j >= 0; --$j) { + if ($syndromes[$i - $j] !== $this->blockSize && $lambda[$j] !== $this->blockSize) { + $tmp ^= $this->alphaTo[$this->modNn($syndromes[$i - $j] + $lambda[$j])]; + } + } + + $omega[$i] = $this->indexOf[$tmp]; + } + + // Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = inv(X(l))**(firstRoot-1) and + // den = lambda_pr(inv(X(l))) all in poly form. + for ($j = $count - 1; $j >= 0; --$j) { + $num1 = 0; + + for ($i = $degOmega; $i >= 0; $i--) { + if ($omega[$i] !== $this->blockSize) { + $num1 ^= $this->alphaTo[$this->modNn($omega[$i] + $i * $root[$j])]; + } + } + + $num2 = $this->alphaTo[$this->modNn($root[$j] * ($this->firstRoot - 1) + $this->blockSize)]; + $den = 0; + + // lambda[i+1] for i even is the formal derivativelambda_pr of lambda[i] + for ($i = min($degLambda, $this->numRoots - 1) & ~1; $i >= 0; $i -= 2) { + if ($lambda[$i + 1] !== $this->blockSize) { + $den ^= $this->alphaTo[$this->modNn($lambda[$i + 1] + $i * $root[$j])]; + } + } + + // Apply error to data + if ($num1 !== 0 && $loc[$j] >= $this->padding) { + $data[$loc[$j] - $this->padding] = $data[$loc[$j] - $this->padding] ^ ( + $this->alphaTo[ + $this->modNn( + $this->indexOf[$num1] + $this->indexOf[$num2] + $this->blockSize - $this->indexOf[$den] + ) + ] + ); + } + } + + if (null !== $erasures) { + if (count($erasures) < $count) { + $erasures->setSize($count); + } + + for ($i = 0; $i < $count; $i++) { + $erasures[$i] = $loc[$i]; + } + } + + return $count; + } + + /** + * Computes $x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, without a slow divide. + */ + private function modNn(int $x) : int + { + while ($x >= $this->blockSize) { + $x -= $this->blockSize; + $x = ($x >> $this->symbolSize) + ($x & $this->blockSize); + } + + return $x; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Common/Version.php b/vendor/bacon/bacon-qr-code/src/Common/Version.php new file mode 100644 index 0000000..68d3d16 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Common/Version.php @@ -0,0 +1,592 @@ +|null + */ + private static ?array $versions = null; + + /** + * @param int[] $alignmentPatternCenters + */ + private function __construct( + int $versionNumber, + array $alignmentPatternCenters, + EcBlocks ...$ecBlocks + ) { + $this->versionNumber = $versionNumber; + $this->alignmentPatternCenters = $alignmentPatternCenters; + $this->ecBlocks = $ecBlocks; + + $totalCodewords = 0; + $ecCodewords = $ecBlocks[0]->getEcCodewordsPerBlock(); + + foreach ($ecBlocks[0]->getEcBlocks() as $ecBlock) { + $totalCodewords += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords); + } + + $this->totalCodewords = $totalCodewords; + } + + /** + * Returns the version number. + */ + public function getVersionNumber() : int + { + return $this->versionNumber; + } + + /** + * Returns the alignment pattern centers. + * + * @return int[] + */ + public function getAlignmentPatternCenters() : array + { + return $this->alignmentPatternCenters; + } + + /** + * Returns the total number of codewords. + */ + public function getTotalCodewords() : int + { + return $this->totalCodewords; + } + + /** + * Calculates the dimension for the current version. + */ + public function getDimensionForVersion() : int + { + return 17 + 4 * $this->versionNumber; + } + + /** + * Returns the number of EC blocks for a specific EC level. + */ + public function getEcBlocksForLevel(ErrorCorrectionLevel $ecLevel) : EcBlocks + { + return $this->ecBlocks[$ecLevel->ordinal()]; + } + + /** + * Gets a provisional version number for a specific dimension. + * + * @throws InvalidArgumentException if dimension is not 1 mod 4 + */ + public static function getProvisionalVersionForDimension(int $dimension) : self + { + if (1 !== $dimension % 4) { + throw new InvalidArgumentException('Dimension is not 1 mod 4'); + } + + return self::getVersionForNumber(intdiv($dimension - 17, 4)); + } + + /** + * Gets a version instance for a specific version number. + * + * @throws InvalidArgumentException if version number is out of range + */ + public static function getVersionForNumber(int $versionNumber) : self + { + if ($versionNumber < 1 || $versionNumber > 40) { + throw new InvalidArgumentException('Version number must be between 1 and 40'); + } + + return self::versions()[$versionNumber - 1]; + } + + /** + * Decodes version information from an integer and returns the version. + */ + public static function decodeVersionInformation(int $versionBits) : ?self + { + $bestDifference = PHP_INT_MAX; + $bestVersion = 0; + + foreach (self::VERSION_DECODE_INFO as $i => $targetVersion) { + if ($targetVersion === $versionBits) { + return self::getVersionForNumber($i + 7); + } + + $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion); + + if ($bitsDifference < $bestDifference) { + $bestVersion = $i + 7; + $bestDifference = $bitsDifference; + } + } + + if ($bestDifference <= 3) { + return self::getVersionForNumber($bestVersion); + } + + return null; + } + + /** + * Builds the function pattern for the current version. + */ + public function buildFunctionPattern() : BitMatrix + { + $dimension = $this->getDimensionForVersion(); + $bitMatrix = new BitMatrix($dimension); + + // Top left finder pattern + separator + format + $bitMatrix->setRegion(0, 0, 9, 9); + // Top right finder pattern + separator + format + $bitMatrix->setRegion($dimension - 8, 0, 8, 9); + // Bottom left finder pattern + separator + format + $bitMatrix->setRegion(0, $dimension - 8, 9, 8); + + // Alignment patterns + $max = count($this->alignmentPatternCenters); + + for ($x = 0; $x < $max; ++$x) { + $i = $this->alignmentPatternCenters[$x] - 2; + + for ($y = 0; $y < $max; ++$y) { + if (($x === 0 && ($y === 0 || $y === $max - 1)) || ($x === $max - 1 && $y === 0)) { + // No alignment patterns near the three finder paterns + continue; + } + + $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5); + } + } + + // Vertical timing pattern + $bitMatrix->setRegion(6, 9, 1, $dimension - 17); + // Horizontal timing pattern + $bitMatrix->setRegion(9, 6, $dimension - 17, 1); + + if ($this->versionNumber > 6) { + // Version info, top right + $bitMatrix->setRegion($dimension - 11, 0, 3, 6); + // Version info, bottom left + $bitMatrix->setRegion(0, $dimension - 11, 6, 3); + } + + return $bitMatrix; + } + + /** + * Returns a string representation for the version. + */ + public function __toString() : string + { + return (string) $this->versionNumber; + } + + /** + * Build and cache a specific version. + * + * See ISO 18004:2006 6.5.1 Table 9. + * + * @return array + */ + private static function versions() : array + { + if (null !== self::$versions) { + return self::$versions; + } + + return self::$versions = [ + new self( + 1, + [], + new EcBlocks(7, new EcBlock(1, 19)), + new EcBlocks(10, new EcBlock(1, 16)), + new EcBlocks(13, new EcBlock(1, 13)), + new EcBlocks(17, new EcBlock(1, 9)) + ), + new self( + 2, + [6, 18], + new EcBlocks(10, new EcBlock(1, 34)), + new EcBlocks(16, new EcBlock(1, 28)), + new EcBlocks(22, new EcBlock(1, 22)), + new EcBlocks(28, new EcBlock(1, 16)) + ), + new self( + 3, + [6, 22], + new EcBlocks(15, new EcBlock(1, 55)), + new EcBlocks(26, new EcBlock(1, 44)), + new EcBlocks(18, new EcBlock(2, 17)), + new EcBlocks(22, new EcBlock(2, 13)) + ), + new self( + 4, + [6, 26], + new EcBlocks(20, new EcBlock(1, 80)), + new EcBlocks(18, new EcBlock(2, 32)), + new EcBlocks(26, new EcBlock(2, 24)), + new EcBlocks(16, new EcBlock(4, 9)) + ), + new self( + 5, + [6, 30], + new EcBlocks(26, new EcBlock(1, 108)), + new EcBlocks(24, new EcBlock(2, 43)), + new EcBlocks(18, new EcBlock(2, 15), new EcBlock(2, 16)), + new EcBlocks(22, new EcBlock(2, 11), new EcBlock(2, 12)) + ), + new self( + 6, + [6, 34], + new EcBlocks(18, new EcBlock(2, 68)), + new EcBlocks(16, new EcBlock(4, 27)), + new EcBlocks(24, new EcBlock(4, 19)), + new EcBlocks(28, new EcBlock(4, 15)) + ), + new self( + 7, + [6, 22, 38], + new EcBlocks(20, new EcBlock(2, 78)), + new EcBlocks(18, new EcBlock(4, 31)), + new EcBlocks(18, new EcBlock(2, 14), new EcBlock(4, 15)), + new EcBlocks(26, new EcBlock(4, 13), new EcBlock(1, 14)) + ), + new self( + 8, + [6, 24, 42], + new EcBlocks(24, new EcBlock(2, 97)), + new EcBlocks(22, new EcBlock(2, 38), new EcBlock(2, 39)), + new EcBlocks(22, new EcBlock(4, 18), new EcBlock(2, 19)), + new EcBlocks(26, new EcBlock(4, 14), new EcBlock(2, 15)) + ), + new self( + 9, + [6, 26, 46], + new EcBlocks(30, new EcBlock(2, 116)), + new EcBlocks(22, new EcBlock(3, 36), new EcBlock(2, 37)), + new EcBlocks(20, new EcBlock(4, 16), new EcBlock(4, 17)), + new EcBlocks(24, new EcBlock(4, 12), new EcBlock(4, 13)) + ), + new self( + 10, + [6, 28, 50], + new EcBlocks(18, new EcBlock(2, 68), new EcBlock(2, 69)), + new EcBlocks(26, new EcBlock(4, 43), new EcBlock(1, 44)), + new EcBlocks(24, new EcBlock(6, 19), new EcBlock(2, 20)), + new EcBlocks(28, new EcBlock(6, 15), new EcBlock(2, 16)) + ), + new self( + 11, + [6, 30, 54], + new EcBlocks(20, new EcBlock(4, 81)), + new EcBlocks(30, new EcBlock(1, 50), new EcBlock(4, 51)), + new EcBlocks(28, new EcBlock(4, 22), new EcBlock(4, 23)), + new EcBlocks(24, new EcBlock(3, 12), new EcBlock(8, 13)) + ), + new self( + 12, + [6, 32, 58], + new EcBlocks(24, new EcBlock(2, 92), new EcBlock(2, 93)), + new EcBlocks(22, new EcBlock(6, 36), new EcBlock(2, 37)), + new EcBlocks(26, new EcBlock(4, 20), new EcBlock(6, 21)), + new EcBlocks(28, new EcBlock(7, 14), new EcBlock(4, 15)) + ), + new self( + 13, + [6, 34, 62], + new EcBlocks(26, new EcBlock(4, 107)), + new EcBlocks(22, new EcBlock(8, 37), new EcBlock(1, 38)), + new EcBlocks(24, new EcBlock(8, 20), new EcBlock(4, 21)), + new EcBlocks(22, new EcBlock(12, 11), new EcBlock(4, 12)) + ), + new self( + 14, + [6, 26, 46, 66], + new EcBlocks(30, new EcBlock(3, 115), new EcBlock(1, 116)), + new EcBlocks(24, new EcBlock(4, 40), new EcBlock(5, 41)), + new EcBlocks(20, new EcBlock(11, 16), new EcBlock(5, 17)), + new EcBlocks(24, new EcBlock(11, 12), new EcBlock(5, 13)) + ), + new self( + 15, + [6, 26, 48, 70], + new EcBlocks(22, new EcBlock(5, 87), new EcBlock(1, 88)), + new EcBlocks(24, new EcBlock(5, 41), new EcBlock(5, 42)), + new EcBlocks(30, new EcBlock(5, 24), new EcBlock(7, 25)), + new EcBlocks(24, new EcBlock(11, 12), new EcBlock(7, 13)) + ), + new self( + 16, + [6, 26, 50, 74], + new EcBlocks(24, new EcBlock(5, 98), new EcBlock(1, 99)), + new EcBlocks(28, new EcBlock(7, 45), new EcBlock(3, 46)), + new EcBlocks(24, new EcBlock(15, 19), new EcBlock(2, 20)), + new EcBlocks(30, new EcBlock(3, 15), new EcBlock(13, 16)) + ), + new self( + 17, + [6, 30, 54, 78], + new EcBlocks(28, new EcBlock(1, 107), new EcBlock(5, 108)), + new EcBlocks(28, new EcBlock(10, 46), new EcBlock(1, 47)), + new EcBlocks(28, new EcBlock(1, 22), new EcBlock(15, 23)), + new EcBlocks(28, new EcBlock(2, 14), new EcBlock(17, 15)) + ), + new self( + 18, + [6, 30, 56, 82], + new EcBlocks(30, new EcBlock(5, 120), new EcBlock(1, 121)), + new EcBlocks(26, new EcBlock(9, 43), new EcBlock(4, 44)), + new EcBlocks(28, new EcBlock(17, 22), new EcBlock(1, 23)), + new EcBlocks(28, new EcBlock(2, 14), new EcBlock(19, 15)) + ), + new self( + 19, + [6, 30, 58, 86], + new EcBlocks(28, new EcBlock(3, 113), new EcBlock(4, 114)), + new EcBlocks(26, new EcBlock(3, 44), new EcBlock(11, 45)), + new EcBlocks(26, new EcBlock(17, 21), new EcBlock(4, 22)), + new EcBlocks(26, new EcBlock(9, 13), new EcBlock(16, 14)) + ), + new self( + 20, + [6, 34, 62, 90], + new EcBlocks(28, new EcBlock(3, 107), new EcBlock(5, 108)), + new EcBlocks(26, new EcBlock(3, 41), new EcBlock(13, 42)), + new EcBlocks(30, new EcBlock(15, 24), new EcBlock(5, 25)), + new EcBlocks(28, new EcBlock(15, 15), new EcBlock(10, 16)) + ), + new self( + 21, + [6, 28, 50, 72, 94], + new EcBlocks(28, new EcBlock(4, 116), new EcBlock(4, 117)), + new EcBlocks(26, new EcBlock(17, 42)), + new EcBlocks(28, new EcBlock(17, 22), new EcBlock(6, 23)), + new EcBlocks(30, new EcBlock(19, 16), new EcBlock(6, 17)) + ), + new self( + 22, + [6, 26, 50, 74, 98], + new EcBlocks(28, new EcBlock(2, 111), new EcBlock(7, 112)), + new EcBlocks(28, new EcBlock(17, 46)), + new EcBlocks(30, new EcBlock(7, 24), new EcBlock(16, 25)), + new EcBlocks(24, new EcBlock(34, 13)) + ), + new self( + 23, + [6, 30, 54, 78, 102], + new EcBlocks(30, new EcBlock(4, 121), new EcBlock(5, 122)), + new EcBlocks(28, new EcBlock(4, 47), new EcBlock(14, 48)), + new EcBlocks(30, new EcBlock(11, 24), new EcBlock(14, 25)), + new EcBlocks(30, new EcBlock(16, 15), new EcBlock(14, 16)) + ), + new self( + 24, + [6, 28, 54, 80, 106], + new EcBlocks(30, new EcBlock(6, 117), new EcBlock(4, 118)), + new EcBlocks(28, new EcBlock(6, 45), new EcBlock(14, 46)), + new EcBlocks(30, new EcBlock(11, 24), new EcBlock(16, 25)), + new EcBlocks(30, new EcBlock(30, 16), new EcBlock(2, 17)) + ), + new self( + 25, + [6, 32, 58, 84, 110], + new EcBlocks(26, new EcBlock(8, 106), new EcBlock(4, 107)), + new EcBlocks(28, new EcBlock(8, 47), new EcBlock(13, 48)), + new EcBlocks(30, new EcBlock(7, 24), new EcBlock(22, 25)), + new EcBlocks(30, new EcBlock(22, 15), new EcBlock(13, 16)) + ), + new self( + 26, + [6, 30, 58, 86, 114], + new EcBlocks(28, new EcBlock(10, 114), new EcBlock(2, 115)), + new EcBlocks(28, new EcBlock(19, 46), new EcBlock(4, 47)), + new EcBlocks(28, new EcBlock(28, 22), new EcBlock(6, 23)), + new EcBlocks(30, new EcBlock(33, 16), new EcBlock(4, 17)) + ), + new self( + 27, + [6, 34, 62, 90, 118], + new EcBlocks(30, new EcBlock(8, 122), new EcBlock(4, 123)), + new EcBlocks(28, new EcBlock(22, 45), new EcBlock(3, 46)), + new EcBlocks(30, new EcBlock(8, 23), new EcBlock(26, 24)), + new EcBlocks(30, new EcBlock(12, 15), new EcBlock(28, 16)) + ), + new self( + 28, + [6, 26, 50, 74, 98, 122], + new EcBlocks(30, new EcBlock(3, 117), new EcBlock(10, 118)), + new EcBlocks(28, new EcBlock(3, 45), new EcBlock(23, 46)), + new EcBlocks(30, new EcBlock(4, 24), new EcBlock(31, 25)), + new EcBlocks(30, new EcBlock(11, 15), new EcBlock(31, 16)) + ), + new self( + 29, + [6, 30, 54, 78, 102, 126], + new EcBlocks(30, new EcBlock(7, 116), new EcBlock(7, 117)), + new EcBlocks(28, new EcBlock(21, 45), new EcBlock(7, 46)), + new EcBlocks(30, new EcBlock(1, 23), new EcBlock(37, 24)), + new EcBlocks(30, new EcBlock(19, 15), new EcBlock(26, 16)) + ), + new self( + 30, + [6, 26, 52, 78, 104, 130], + new EcBlocks(30, new EcBlock(5, 115), new EcBlock(10, 116)), + new EcBlocks(28, new EcBlock(19, 47), new EcBlock(10, 48)), + new EcBlocks(30, new EcBlock(15, 24), new EcBlock(25, 25)), + new EcBlocks(30, new EcBlock(23, 15), new EcBlock(25, 16)) + ), + new self( + 31, + [6, 30, 56, 82, 108, 134], + new EcBlocks(30, new EcBlock(13, 115), new EcBlock(3, 116)), + new EcBlocks(28, new EcBlock(2, 46), new EcBlock(29, 47)), + new EcBlocks(30, new EcBlock(42, 24), new EcBlock(1, 25)), + new EcBlocks(30, new EcBlock(23, 15), new EcBlock(28, 16)) + ), + new self( + 32, + [6, 34, 60, 86, 112, 138], + new EcBlocks(30, new EcBlock(17, 115)), + new EcBlocks(28, new EcBlock(10, 46), new EcBlock(23, 47)), + new EcBlocks(30, new EcBlock(10, 24), new EcBlock(35, 25)), + new EcBlocks(30, new EcBlock(19, 15), new EcBlock(35, 16)) + ), + new self( + 33, + [6, 30, 58, 86, 114, 142], + new EcBlocks(30, new EcBlock(17, 115), new EcBlock(1, 116)), + new EcBlocks(28, new EcBlock(14, 46), new EcBlock(21, 47)), + new EcBlocks(30, new EcBlock(29, 24), new EcBlock(19, 25)), + new EcBlocks(30, new EcBlock(11, 15), new EcBlock(46, 16)) + ), + new self( + 34, + [6, 34, 62, 90, 118, 146], + new EcBlocks(30, new EcBlock(13, 115), new EcBlock(6, 116)), + new EcBlocks(28, new EcBlock(14, 46), new EcBlock(23, 47)), + new EcBlocks(30, new EcBlock(44, 24), new EcBlock(7, 25)), + new EcBlocks(30, new EcBlock(59, 16), new EcBlock(1, 17)) + ), + new self( + 35, + [6, 30, 54, 78, 102, 126, 150], + new EcBlocks(30, new EcBlock(12, 121), new EcBlock(7, 122)), + new EcBlocks(28, new EcBlock(12, 47), new EcBlock(26, 48)), + new EcBlocks(30, new EcBlock(39, 24), new EcBlock(14, 25)), + new EcBlocks(30, new EcBlock(22, 15), new EcBlock(41, 16)) + ), + new self( + 36, + [6, 24, 50, 76, 102, 128, 154], + new EcBlocks(30, new EcBlock(6, 121), new EcBlock(14, 122)), + new EcBlocks(28, new EcBlock(6, 47), new EcBlock(34, 48)), + new EcBlocks(30, new EcBlock(46, 24), new EcBlock(10, 25)), + new EcBlocks(30, new EcBlock(2, 15), new EcBlock(64, 16)) + ), + new self( + 37, + [6, 28, 54, 80, 106, 132, 158], + new EcBlocks(30, new EcBlock(17, 122), new EcBlock(4, 123)), + new EcBlocks(28, new EcBlock(29, 46), new EcBlock(14, 47)), + new EcBlocks(30, new EcBlock(49, 24), new EcBlock(10, 25)), + new EcBlocks(30, new EcBlock(24, 15), new EcBlock(46, 16)) + ), + new self( + 38, + [6, 32, 58, 84, 110, 136, 162], + new EcBlocks(30, new EcBlock(4, 122), new EcBlock(18, 123)), + new EcBlocks(28, new EcBlock(13, 46), new EcBlock(32, 47)), + new EcBlocks(30, new EcBlock(48, 24), new EcBlock(14, 25)), + new EcBlocks(30, new EcBlock(42, 15), new EcBlock(32, 16)) + ), + new self( + 39, + [6, 26, 54, 82, 110, 138, 166], + new EcBlocks(30, new EcBlock(20, 117), new EcBlock(4, 118)), + new EcBlocks(28, new EcBlock(40, 47), new EcBlock(7, 48)), + new EcBlocks(30, new EcBlock(43, 24), new EcBlock(22, 25)), + new EcBlocks(30, new EcBlock(10, 15), new EcBlock(67, 16)) + ), + new self( + 40, + [6, 30, 58, 86, 114, 142, 170], + new EcBlocks(30, new EcBlock(19, 118), new EcBlock(6, 119)), + new EcBlocks(28, new EcBlock(18, 47), new EcBlock(31, 48)), + new EcBlocks(30, new EcBlock(34, 24), new EcBlock(34, 25)), + new EcBlocks(30, new EcBlock(20, 15), new EcBlock(61, 16)) + ), + ]; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php b/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php new file mode 100644 index 0000000..b1dc5c4 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Encoder/BlockPair.php @@ -0,0 +1,44 @@ + $dataBytes Data bytes in the block. + * @param SplFixedArray $errorCorrectionBytes Error correction bytes in the block. + */ + public function __construct( + private readonly SplFixedArray $dataBytes, + private readonly SplFixedArray $errorCorrectionBytes + ) { + } + + /** + * Gets the data bytes. + * + * @return SplFixedArray + */ + public function getDataBytes() : SplFixedArray + { + return $this->dataBytes; + } + + /** + * Gets the error correction bytes. + * + * @return SplFixedArray + */ + public function getErrorCorrectionBytes() : SplFixedArray + { + return $this->errorCorrectionBytes; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php b/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php new file mode 100644 index 0000000..eefcf1c --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Encoder/ByteMatrix.php @@ -0,0 +1,134 @@ +> + */ + private SplFixedArray $bytes; + + public function __construct(private readonly int $width, private readonly int $height) + { + $this->bytes = new SplFixedArray($height); + + for ($y = 0; $y < $height; ++$y) { + $this->bytes[$y] = SplFixedArray::fromArray(array_fill(0, $width, 0)); + } + } + + /** + * Gets the width of the matrix. + */ + public function getWidth() : int + { + return $this->width; + } + + /** + * Gets the height of the matrix. + */ + public function getHeight() : int + { + return $this->height; + } + + /** + * Gets the internal representation of the matrix. + * + * @return SplFixedArray> + */ + public function getArray() : SplFixedArray + { + return $this->bytes; + } + + /** + * @return Traversable + */ + public function getBytes() : Traversable + { + foreach ($this->bytes as $row) { + foreach ($row as $byte) { + yield $byte; + } + } + } + + /** + * Gets the byte for a specific position. + */ + public function get(int $x, int $y) : int + { + return $this->bytes[$y][$x]; + } + + /** + * Sets the byte for a specific position. + */ + public function set(int $x, int $y, int $value) : void + { + $this->bytes[$y][$x] = $value; + } + + /** + * Clears the matrix with a specific value. + */ + public function clear(int $value) : void + { + for ($y = 0; $y < $this->height; ++$y) { + for ($x = 0; $x < $this->width; ++$x) { + $this->bytes[$y][$x] = $value; + } + } + } + + public function __clone() + { + $this->bytes = clone $this->bytes; + + foreach ($this->bytes as $index => $row) { + $this->bytes[$index] = clone $row; + } + } + + /** + * Returns a string representation of the matrix. + */ + public function __toString() : string + { + $result = ''; + + for ($y = 0; $y < $this->height; $y++) { + for ($x = 0; $x < $this->width; $x++) { + switch ($this->bytes[$y][$x]) { + case 0: + $result .= ' 0'; + break; + + case 1: + $result .= ' 1'; + break; + + default: + $result .= ' '; + break; + } + } + + $result .= "\n"; + } + + return $result; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php b/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php new file mode 100644 index 0000000..a7e00ff --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php @@ -0,0 +1,666 @@ + + */ + private static array $codecs = []; + + /** + * Encodes "content" with the error correction level "ecLevel". + */ + public static function encode( + string $content, + ErrorCorrectionLevel $ecLevel, + string $encoding = self::DEFAULT_BYTE_MODE_ENCODING, + ?Version $forcedVersion = null, + // Barcode scanner might not be able to read the encoded message of the QR code with the prefix ECI of UTF-8 + bool $prefixEci = true + ) : QrCode { + // Pick an encoding mode appropriate for the content. Note that this + // will not attempt to use multiple modes / segments even if that were + // more efficient. Would be nice. + $mode = self::chooseMode($content, $encoding); + + // This will store the header information, like mode and length, as well + // as "header" segments like an ECI segment. + $headerBits = new BitArray(); + + // Append ECI segment if applicable + if ($prefixEci && Mode::BYTE() === $mode && self::DEFAULT_BYTE_MODE_ENCODING !== $encoding) { + $eci = CharacterSetEci::getCharacterSetEciByName($encoding); + + if (null !== $eci) { + self::appendEci($eci, $headerBits); + } + } + + // (With ECI in place,) Write the mode marker + self::appendModeInfo($mode, $headerBits); + + // Collect data within the main segment, separately, to count its size + // if needed. Don't add it to main payload yet. + $dataBits = new BitArray(); + self::appendBytes($content, $mode, $dataBits, $encoding); + + // Hard part: need to know version to know how many bits length takes. + // But need to know how many bits it takes to know version. First we + // take a guess at version by assuming version will be the minimum, 1: + $provisionalBitsNeeded = $headerBits->getSize() + + $mode->getCharacterCountBits(Version::getVersionForNumber(1)) + + $dataBits->getSize(); + $provisionalVersion = self::chooseVersion($provisionalBitsNeeded, $ecLevel); + + // Use that guess to calculate the right version. I am still not sure + // this works in 100% of cases. + $bitsNeeded = $headerBits->getSize() + + $mode->getCharacterCountBits($provisionalVersion) + + $dataBits->getSize(); + $version = self::chooseVersion($bitsNeeded, $ecLevel); + + if (null !== $forcedVersion) { + // Forced version check + if ($version->getVersionNumber() <= $forcedVersion->getVersionNumber()) { + // Calculated minimum version is same or equal as forced version + $version = $forcedVersion; + } else { + throw new WriterException( + 'Invalid version! Calculated version: ' + . $version->getVersionNumber() + . ', requested version: ' + . $forcedVersion->getVersionNumber() + ); + } + } + + $headerAndDataBits = new BitArray(); + $headerAndDataBits->appendBitArray($headerBits); + + // Find "length" of main segment and write it. + $numLetters = match ($mode) { + Mode::BYTE() => $dataBits->getSizeInBytes(), + Mode::NUMERIC(), Mode::ALPHANUMERIC() => strlen($content), + Mode::KANJI() => iconv_strlen($content, 'utf-8'), + }; + self::appendLengthInfo($numLetters, $version, $mode, $headerAndDataBits); + + // Put data together into the overall payload. + $headerAndDataBits->appendBitArray($dataBits); + $ecBlocks = $version->getEcBlocksForLevel($ecLevel); + $numDataBytes = $version->getTotalCodewords() - $ecBlocks->getTotalEcCodewords(); + + // Terminate the bits properly. + self::terminateBits($numDataBytes, $headerAndDataBits); + + // Interleave data bits with error correction code. + $finalBits = self::interleaveWithEcBytes( + $headerAndDataBits, + $version->getTotalCodewords(), + $numDataBytes, + $ecBlocks->getNumBlocks() + ); + + // Choose the mask pattern. + $dimension = $version->getDimensionForVersion(); + $matrix = new ByteMatrix($dimension, $dimension); + $maskPattern = self::chooseMaskPattern($finalBits, $ecLevel, $version, $matrix); + + // Build the matrix. + MatrixUtil::buildMatrix($finalBits, $ecLevel, $version, $maskPattern, $matrix); + + return new QrCode($mode, $ecLevel, $version, $maskPattern, $matrix); + } + + /** + * Gets the alphanumeric code for a byte. + */ + private static function getAlphanumericCode(int $byte) : int + { + return self::ALPHANUMERIC_TABLE[$byte] ?? -1; + } + + /** + * Chooses the best mode for a given content. + */ + private static function chooseMode(string $content, ?string $encoding = null) : Mode + { + if ('' === $content) { + return Mode::BYTE(); + } + + if (null !== $encoding && 0 === strcasecmp($encoding, 'SHIFT-JIS')) { + return self::isOnlyDoubleByteKanji($content) ? Mode::KANJI() : Mode::BYTE(); + } + + if (ctype_digit($content)) { + return Mode::NUMERIC(); + } + + if (self::isOnlyAlphanumeric($content)) { + return Mode::ALPHANUMERIC(); + } + + return Mode::BYTE(); + } + + /** + * Calculates the mask penalty for a matrix. + */ + private static function calculateMaskPenalty(ByteMatrix $matrix) : int + { + return ( + MaskUtil::applyMaskPenaltyRule1($matrix) + + MaskUtil::applyMaskPenaltyRule2($matrix) + + MaskUtil::applyMaskPenaltyRule3($matrix) + + MaskUtil::applyMaskPenaltyRule4($matrix) + ); + } + + /** + * Checks if content only consists of double-byte kanji characters (or is empty). + */ + private static function isOnlyDoubleByteKanji(string $content) : bool + { + $bytes = @iconv('utf-8', 'SHIFT-JIS', $content); + + if (false === $bytes) { + return false; + } + + $length = strlen($bytes); + + if (0 !== $length % 2) { + return false; + } + + for ($i = 0; $i < $length; $i += 2) { + $byte = ord($bytes[$i]); + + if (($byte < 0x81 || $byte > 0x9f) && $byte < 0xe0 || $byte > 0xeb) { + return false; + } + } + + return true; + } + + /** + * Checks if content only consists of alphanumeric characters (or is empty). + */ + private static function isOnlyAlphanumeric(string $content) : bool + { + return strlen($content) === strspn($content, self::ALPHANUMERIC_CHARS); + } + + /** + * Chooses the best mask pattern for a matrix. + */ + private static function chooseMaskPattern( + BitArray $bits, + ErrorCorrectionLevel $ecLevel, + Version $version, + ByteMatrix $matrix + ) : int { + $minPenalty = PHP_INT_MAX; + $bestMaskPattern = -1; + + for ($maskPattern = 0; $maskPattern < QrCode::NUM_MASK_PATTERNS; ++$maskPattern) { + MatrixUtil::buildMatrix($bits, $ecLevel, $version, $maskPattern, $matrix); + $penalty = self::calculateMaskPenalty($matrix); + + if ($penalty < $minPenalty) { + $minPenalty = $penalty; + $bestMaskPattern = $maskPattern; + } + } + + return $bestMaskPattern; + } + + /** + * Chooses the best version for the input. + * + * @throws WriterException if data is too big + */ + private static function chooseVersion(int $numInputBits, ErrorCorrectionLevel $ecLevel) : Version + { + for ($versionNum = 1; $versionNum <= 40; ++$versionNum) { + $version = Version::getVersionForNumber($versionNum); + $numBytes = $version->getTotalCodewords(); + + $ecBlocks = $version->getEcBlocksForLevel($ecLevel); + $numEcBytes = $ecBlocks->getTotalEcCodewords(); + + $numDataBytes = $numBytes - $numEcBytes; + $totalInputBytes = intdiv($numInputBits + 8, 8); + + if ($numDataBytes >= $totalInputBytes) { + return $version; + } + } + + throw new WriterException('Data too big'); + } + + /** + * Terminates the bits in a bit array. + * + * @throws WriterException if data bits cannot fit in the QR code + * @throws WriterException if bits size does not equal the capacity + */ + private static function terminateBits(int $numDataBytes, BitArray $bits) : void + { + $capacity = $numDataBytes << 3; + + if ($bits->getSize() > $capacity) { + throw new WriterException('Data bits cannot fit in the QR code'); + } + + for ($i = 0; $i < 4 && $bits->getSize() < $capacity; ++$i) { + $bits->appendBit(false); + } + + $numBitsInLastByte = $bits->getSize() & 0x7; + + if ($numBitsInLastByte > 0) { + for ($i = $numBitsInLastByte; $i < 8; ++$i) { + $bits->appendBit(false); + } + } + + $numPaddingBytes = $numDataBytes - $bits->getSizeInBytes(); + + for ($i = 0; $i < $numPaddingBytes; ++$i) { + $bits->appendBits(0 === ($i & 0x1) ? 0xec : 0x11, 8); + } + + if ($bits->getSize() !== $capacity) { + throw new WriterException('Bits size does not equal capacity'); + } + } + + /** + * Gets number of data- and EC bytes for a block ID. + * + * @return int[] + * @throws WriterException if block ID is too large + * @throws WriterException if EC bytes mismatch + * @throws WriterException if RS blocks mismatch + * @throws WriterException if total bytes mismatch + */ + private static function getNumDataBytesAndNumEcBytesForBlockId( + int $numTotalBytes, + int $numDataBytes, + int $numRsBlocks, + int $blockId + ) : array { + if ($blockId >= $numRsBlocks) { + throw new WriterException('Block ID too large'); + } + + $numRsBlocksInGroup2 = $numTotalBytes % $numRsBlocks; + $numRsBlocksInGroup1 = $numRsBlocks - $numRsBlocksInGroup2; + $numTotalBytesInGroup1 = intdiv($numTotalBytes, $numRsBlocks); + $numTotalBytesInGroup2 = $numTotalBytesInGroup1 + 1; + $numDataBytesInGroup1 = intdiv($numDataBytes, $numRsBlocks); + $numDataBytesInGroup2 = $numDataBytesInGroup1 + 1; + $numEcBytesInGroup1 = $numTotalBytesInGroup1 - $numDataBytesInGroup1; + $numEcBytesInGroup2 = $numTotalBytesInGroup2 - $numDataBytesInGroup2; + + if ($numEcBytesInGroup1 !== $numEcBytesInGroup2) { + throw new WriterException('EC bytes mismatch'); + } + + if ($numRsBlocks !== $numRsBlocksInGroup1 + $numRsBlocksInGroup2) { + throw new WriterException('RS blocks mismatch'); + } + + if ($numTotalBytes !== + (($numDataBytesInGroup1 + $numEcBytesInGroup1) * $numRsBlocksInGroup1) + + (($numDataBytesInGroup2 + $numEcBytesInGroup2) * $numRsBlocksInGroup2) + ) { + throw new WriterException('Total bytes mismatch'); + } + + if ($blockId < $numRsBlocksInGroup1) { + return [$numDataBytesInGroup1, $numEcBytesInGroup1]; + } else { + return [$numDataBytesInGroup2, $numEcBytesInGroup2]; + } + } + + /** + * Interleaves data with EC bytes. + * + * @throws WriterException if number of bits and data bytes does not match + * @throws WriterException if data bytes does not match offset + * @throws WriterException if an interleaving error occurs + */ + private static function interleaveWithEcBytes( + BitArray $bits, + int $numTotalBytes, + int $numDataBytes, + int $numRsBlocks + ) : BitArray { + if ($bits->getSizeInBytes() !== $numDataBytes) { + throw new WriterException('Number of bits and data bytes does not match'); + } + + $dataBytesOffset = 0; + $maxNumDataBytes = 0; + $maxNumEcBytes = 0; + + $blocks = new SplFixedArray($numRsBlocks); + + for ($i = 0; $i < $numRsBlocks; ++$i) { + list($numDataBytesInBlock, $numEcBytesInBlock) = self::getNumDataBytesAndNumEcBytesForBlockId( + $numTotalBytes, + $numDataBytes, + $numRsBlocks, + $i + ); + + $size = $numDataBytesInBlock; + $dataBytes = $bits->toBytes(8 * $dataBytesOffset, $size); + $ecBytes = self::generateEcBytes($dataBytes, $numEcBytesInBlock); + $blocks[$i] = new BlockPair($dataBytes, $ecBytes); + + $maxNumDataBytes = max($maxNumDataBytes, $size); + $maxNumEcBytes = max($maxNumEcBytes, count($ecBytes)); + $dataBytesOffset += $numDataBytesInBlock; + } + + if ($numDataBytes !== $dataBytesOffset) { + throw new WriterException('Data bytes does not match offset'); + } + + $result = new BitArray(); + + for ($i = 0; $i < $maxNumDataBytes; ++$i) { + foreach ($blocks as $block) { + $dataBytes = $block->getDataBytes(); + + if ($i < count($dataBytes)) { + $result->appendBits($dataBytes[$i], 8); + } + } + } + + for ($i = 0; $i < $maxNumEcBytes; ++$i) { + foreach ($blocks as $block) { + $ecBytes = $block->getErrorCorrectionBytes(); + + if ($i < count($ecBytes)) { + $result->appendBits($ecBytes[$i], 8); + } + } + } + + if ($numTotalBytes !== $result->getSizeInBytes()) { + throw new WriterException( + 'Interleaving error: ' . $numTotalBytes . ' and ' . $result->getSizeInBytes() . ' differ' + ); + } + + return $result; + } + + /** + * Generates EC bytes for given data. + * + * @param SplFixedArray $dataBytes + * @return SplFixedArray + */ + private static function generateEcBytes(SplFixedArray $dataBytes, int $numEcBytesInBlock) : SplFixedArray + { + $numDataBytes = count($dataBytes); + $toEncode = new SplFixedArray($numDataBytes + $numEcBytesInBlock); + + for ($i = 0; $i < $numDataBytes; $i++) { + $toEncode[$i] = $dataBytes[$i]; + } + + $ecBytes = new SplFixedArray($numEcBytesInBlock); + $codec = self::getCodec($numDataBytes, $numEcBytesInBlock); + $codec->encode($toEncode, $ecBytes); + + return $ecBytes; + } + + /** + * Gets an RS codec and caches it. + */ + private static function getCodec(int $numDataBytes, int $numEcBytesInBlock) : ReedSolomonCodec + { + $cacheId = $numDataBytes . '-' . $numEcBytesInBlock; + + if (isset(self::$codecs[$cacheId])) { + return self::$codecs[$cacheId]; + } + + return self::$codecs[$cacheId] = new ReedSolomonCodec( + 8, + 0x11d, + 0, + 1, + $numEcBytesInBlock, + 255 - $numDataBytes - $numEcBytesInBlock + ); + } + + /** + * Appends mode information to a bit array. + */ + private static function appendModeInfo(Mode $mode, BitArray $bits) : void + { + $bits->appendBits($mode->getBits(), 4); + } + + /** + * Appends length information to a bit array. + * + * @throws WriterException if num letters is bigger than expected + */ + private static function appendLengthInfo(int $numLetters, Version $version, Mode $mode, BitArray $bits) : void + { + $numBits = $mode->getCharacterCountBits($version); + + if ($numLetters >= (1 << $numBits)) { + throw new WriterException($numLetters . ' is bigger than ' . ((1 << $numBits) - 1)); + } + + $bits->appendBits($numLetters, $numBits); + } + + /** + * Appends bytes to a bit array in a specific mode. + */ + private static function appendBytes(string $content, Mode $mode, BitArray $bits, string $encoding) : void + { + match ($mode) { + Mode::NUMERIC() => self::appendNumericBytes($content, $bits), + Mode::ALPHANUMERIC() => self::appendAlphanumericBytes($content, $bits), + Mode::BYTE() => self::append8BitBytes($content, $bits, $encoding), + Mode::KANJI() => self::appendKanjiBytes($content, $bits), + }; + } + + /** + * Appends numeric bytes to a bit array. + */ + private static function appendNumericBytes(string $content, BitArray $bits) : void + { + $length = strlen($content); + $i = 0; + + while ($i < $length) { + $num1 = (int) $content[$i]; + + if ($i + 2 < $length) { + // Encode three numeric letters in ten bits. + $num2 = (int) $content[$i + 1]; + $num3 = (int) $content[$i + 2]; + $bits->appendBits($num1 * 100 + $num2 * 10 + $num3, 10); + $i += 3; + } elseif ($i + 1 < $length) { + // Encode two numeric letters in seven bits. + $num2 = (int) $content[$i + 1]; + $bits->appendBits($num1 * 10 + $num2, 7); + $i += 2; + } else { + // Encode one numeric letter in four bits. + $bits->appendBits($num1, 4); + ++$i; + } + } + } + + /** + * Appends alpha-numeric bytes to a bit array. + * + * @throws WriterException if an invalid alphanumeric code was found + */ + private static function appendAlphanumericBytes(string $content, BitArray $bits) : void + { + $length = strlen($content); + $i = 0; + + while ($i < $length) { + $code1 = self::getAlphanumericCode(ord($content[$i])); + + if (-1 === $code1) { + throw new WriterException('Invalid alphanumeric code'); + } + + if ($i + 1 < $length) { + $code2 = self::getAlphanumericCode(ord($content[$i + 1])); + + if (-1 === $code2) { + throw new WriterException('Invalid alphanumeric code'); + } + + // Encode two alphanumeric letters in 11 bits. + $bits->appendBits($code1 * 45 + $code2, 11); + $i += 2; + } else { + // Encode one alphanumeric letter in six bits. + $bits->appendBits($code1, 6); + ++$i; + } + } + } + + /** + * Appends regular 8-bit bytes to a bit array. + * + * @throws WriterException if content cannot be encoded to target encoding + */ + private static function append8BitBytes(string $content, BitArray $bits, string $encoding) : void + { + $bytes = @iconv('utf-8', $encoding, $content); + + if (false === $bytes) { + throw new WriterException('Could not encode content to ' . $encoding); + } + + $length = strlen($bytes); + + for ($i = 0; $i < $length; $i++) { + $bits->appendBits(ord($bytes[$i]), 8); + } + } + + /** + * Appends KANJI bytes to a bit array. + * + * @throws WriterException if content does not seem to be encoded in SHIFT-JIS + * @throws WriterException if an invalid byte sequence occurs + */ + private static function appendKanjiBytes(string $content, BitArray $bits) : void + { + $bytes = @iconv('utf-8', 'SHIFT-JIS', $content); + + if (false === $bytes) { + throw new WriterException('Content could not be converted to SHIFT-JIS'); + } + + if (strlen($bytes) % 2 > 0) { + // We just do a simple length check here. The for loop will check + // individual characters. + throw new WriterException('Content does not seem to be encoded in SHIFT-JIS'); + } + + $length = strlen($bytes); + + for ($i = 0; $i < $length; $i += 2) { + $byte1 = ord($bytes[$i]); + $byte2 = ord($bytes[$i + 1]); + $code = ($byte1 << 8) | $byte2; + + if ($code >= 0x8140 && $code <= 0x9ffc) { + $subtracted = $code - 0x8140; + } elseif ($code >= 0xe040 && $code <= 0xebbf) { + $subtracted = $code - 0xc140; + } else { + throw new WriterException('Invalid byte sequence'); + } + + $encoded = (($subtracted >> 8) * 0xc0) + ($subtracted & 0xff); + + $bits->appendBits($encoded, 13); + } + } + + /** + * Appends ECI information to a bit array. + */ + private static function appendEci(CharacterSetEci $eci, BitArray $bits) : void + { + $mode = Mode::ECI(); + $bits->appendBits($mode->getBits(), 4); + $bits->appendBits($eci->getValue(), 8); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php b/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php new file mode 100644 index 0000000..66f3ff1 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php @@ -0,0 +1,271 @@ +getArray(); + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + + for ($y = 0; $y < $height - 1; ++$y) { + for ($x = 0; $x < $width - 1; ++$x) { + $value = $array[$y][$x]; + + if ($value === $array[$y][$x + 1] + && $value === $array[$y + 1][$x] + && $value === $array[$y + 1][$x + 1] + ) { + ++$penalty; + } + } + } + + return self::N2 * $penalty; + } + + /** + * Applies mask penalty rule 3 and returns the penalty. + * + * Finds consecutive cells of 00001011101 or 10111010000, and gives penalty + * to them. If we find patterns like 000010111010000, we give penalties + * twice (i.e. 40 * 2). + */ + public static function applyMaskPenaltyRule3(ByteMatrix $matrix) : int + { + $penalty = 0; + $array = $matrix->getArray(); + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + + for ($y = 0; $y < $height; ++$y) { + for ($x = 0; $x < $width; ++$x) { + if ($x + 6 < $width + && 1 === $array[$y][$x] + && 0 === $array[$y][$x + 1] + && 1 === $array[$y][$x + 2] + && 1 === $array[$y][$x + 3] + && 1 === $array[$y][$x + 4] + && 0 === $array[$y][$x + 5] + && 1 === $array[$y][$x + 6] + && ( + ( + $x + 10 < $width + && 0 === $array[$y][$x + 7] + && 0 === $array[$y][$x + 8] + && 0 === $array[$y][$x + 9] + && 0 === $array[$y][$x + 10] + ) + || ( + $x - 4 >= 0 + && 0 === $array[$y][$x - 1] + && 0 === $array[$y][$x - 2] + && 0 === $array[$y][$x - 3] + && 0 === $array[$y][$x - 4] + ) + ) + ) { + $penalty += self::N3; + } + + if ($y + 6 < $height + && 1 === $array[$y][$x] + && 0 === $array[$y + 1][$x] + && 1 === $array[$y + 2][$x] + && 1 === $array[$y + 3][$x] + && 1 === $array[$y + 4][$x] + && 0 === $array[$y + 5][$x] + && 1 === $array[$y + 6][$x] + && ( + ( + $y + 10 < $height + && 0 === $array[$y + 7][$x] + && 0 === $array[$y + 8][$x] + && 0 === $array[$y + 9][$x] + && 0 === $array[$y + 10][$x] + ) + || ( + $y - 4 >= 0 + && 0 === $array[$y - 1][$x] + && 0 === $array[$y - 2][$x] + && 0 === $array[$y - 3][$x] + && 0 === $array[$y - 4][$x] + ) + ) + ) { + $penalty += self::N3; + } + } + } + + return $penalty; + } + + /** + * Applies mask penalty rule 4 and returns the penalty. + * + * Calculates the ratio of dark cells and gives penalty if the ratio is far + * from 50%. It gives 10 penalty for 5% distance. + */ + public static function applyMaskPenaltyRule4(ByteMatrix $matrix) : int + { + $numDarkCells = 0; + + $array = $matrix->getArray(); + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + + for ($y = 0; $y < $height; ++$y) { + $arrayY = $array[$y]; + + for ($x = 0; $x < $width; ++$x) { + if (1 === $arrayY[$x]) { + ++$numDarkCells; + } + } + } + + $numTotalCells = $height * $width; + $darkRatio = $numDarkCells / $numTotalCells; + $fixedPercentVariances = (int) floor(abs($darkRatio - 0.5) * 20); + + return $fixedPercentVariances * self::N4; + } + + /** + * Returns the mask bit for "getMaskPattern" at "x" and "y". + * + * See 8.8 of JISX0510:2004 for mask pattern conditions. + * + * @throws InvalidArgumentException if an invalid mask pattern was supplied + */ + public static function getDataMaskBit(int $maskPattern, int $x, int $y) : bool + { + switch ($maskPattern) { + case 0: + $intermediate = ($y + $x) & 0x1; + break; + + case 1: + $intermediate = $y & 0x1; + break; + + case 2: + $intermediate = $x % 3; + break; + + case 3: + $intermediate = ($y + $x) % 3; + break; + + case 4: + $intermediate = (BitUtils::unsignedRightShift($y, 1) + (int) ($x / 3)) & 0x1; + break; + + case 5: + $temp = $y * $x; + $intermediate = ($temp & 0x1) + ($temp % 3); + break; + + case 6: + $temp = $y * $x; + $intermediate = (($temp & 0x1) + ($temp % 3)) & 0x1; + break; + + case 7: + $temp = $y * $x; + $intermediate = (($temp % 3) + (($y + $x) & 0x1)) & 0x1; + break; + + default: + throw new InvalidArgumentException('Invalid mask pattern: ' . $maskPattern); + } + + return 0 == $intermediate; + } + + /** + * Helper function for applyMaskPenaltyRule1. + * + * We need this for doing this calculation in both vertical and horizontal + * orders respectively. + */ + private static function applyMaskPenaltyRule1Internal(ByteMatrix $matrix, bool $isHorizontal) : int + { + $penalty = 0; + $iLimit = $isHorizontal ? $matrix->getHeight() : $matrix->getWidth(); + $jLimit = $isHorizontal ? $matrix->getWidth() : $matrix->getHeight(); + $array = $matrix->getArray(); + + for ($i = 0; $i < $iLimit; ++$i) { + $numSameBitCells = 0; + $prevBit = -1; + + for ($j = 0; $j < $jLimit; $j++) { + $bit = $isHorizontal ? $array[$i][$j] : $array[$j][$i]; + + if ($bit === $prevBit) { + ++$numSameBitCells; + } else { + if ($numSameBitCells >= 5) { + $penalty += self::N1 + ($numSameBitCells - 5); + } + + $numSameBitCells = 1; + $prevBit = $bit; + } + } + + if ($numSameBitCells >= 5) { + $penalty += self::N1 + ($numSameBitCells - 5); + } + } + + return $penalty; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php b/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php new file mode 100644 index 0000000..0967e29 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Encoder/MatrixUtil.php @@ -0,0 +1,513 @@ +clear(-1); + } + + /** + * Builds a complete matrix. + */ + public static function buildMatrix( + BitArray $dataBits, + ErrorCorrectionLevel $level, + Version $version, + int $maskPattern, + ByteMatrix $matrix + ) : void { + self::clearMatrix($matrix); + self::embedBasicPatterns($version, $matrix); + self::embedTypeInfo($level, $maskPattern, $matrix); + self::maybeEmbedVersionInfo($version, $matrix); + self::embedDataBits($dataBits, $maskPattern, $matrix); + } + + /** + * Removes the position detection patterns from a matrix. + * + * This can be useful if you need to render those patterns separately. + */ + public static function removePositionDetectionPatterns(ByteMatrix $matrix) : void + { + $pdpWidth = count(self::POSITION_DETECTION_PATTERN[0]); + + self::removePositionDetectionPattern(0, 0, $matrix); + self::removePositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix); + self::removePositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix); + } + + /** + * Embeds type information into a matrix. + */ + private static function embedTypeInfo(ErrorCorrectionLevel $level, int $maskPattern, ByteMatrix $matrix) : void + { + $typeInfoBits = new BitArray(); + self::makeTypeInfoBits($level, $maskPattern, $typeInfoBits); + + $typeInfoBitsSize = $typeInfoBits->getSize(); + + for ($i = 0; $i < $typeInfoBitsSize; ++$i) { + $bit = $typeInfoBits->get($typeInfoBitsSize - 1 - $i); + + $x1 = self::TYPE_INFO_COORDINATES[$i][0]; + $y1 = self::TYPE_INFO_COORDINATES[$i][1]; + + $matrix->set($x1, $y1, (int) $bit); + + if ($i < 8) { + $x2 = $matrix->getWidth() - $i - 1; + $y2 = 8; + } else { + $x2 = 8; + $y2 = $matrix->getHeight() - 7 + ($i - 8); + } + + $matrix->set($x2, $y2, (int) $bit); + } + } + + /** + * Generates type information bits and appends them to a bit array. + * + * @throws RuntimeException if bit array resulted in invalid size + */ + private static function makeTypeInfoBits(ErrorCorrectionLevel $level, int $maskPattern, BitArray $bits) : void + { + $typeInfo = ($level->getBits() << 3) | $maskPattern; + $bits->appendBits($typeInfo, 5); + + $bchCode = self::calculateBchCode($typeInfo, self::TYPE_INFO_POLY); + $bits->appendBits($bchCode, 10); + + $maskBits = new BitArray(); + $maskBits->appendBits(self::TYPE_INFO_MASK_PATTERN, 15); + $bits->xorBits($maskBits); + + if (15 !== $bits->getSize()) { + throw new RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize()); + } + } + + /** + * Embeds version information if required. + */ + private static function maybeEmbedVersionInfo(Version $version, ByteMatrix $matrix) : void + { + if ($version->getVersionNumber() < 7) { + return; + } + + $versionInfoBits = new BitArray(); + self::makeVersionInfoBits($version, $versionInfoBits); + + $bitIndex = 6 * 3 - 1; + + for ($i = 0; $i < 6; ++$i) { + for ($j = 0; $j < 3; ++$j) { + $bit = $versionInfoBits->get($bitIndex); + --$bitIndex; + + $matrix->set($i, $matrix->getHeight() - 11 + $j, (int) $bit); + $matrix->set($matrix->getHeight() - 11 + $j, $i, (int) $bit); + } + } + } + + /** + * Generates version information bits and appends them to a bit array. + * + * @throws RuntimeException if bit array resulted in invalid size + */ + private static function makeVersionInfoBits(Version $version, BitArray $bits) : void + { + $bits->appendBits($version->getVersionNumber(), 6); + + $bchCode = self::calculateBchCode($version->getVersionNumber(), self::VERSION_INFO_POLY); + $bits->appendBits($bchCode, 12); + + if (18 !== $bits->getSize()) { + throw new RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize()); + } + } + + /** + * Calculates the BCH code for a value and a polynomial. + */ + private static function calculateBchCode(int $value, int $poly) : int + { + $msbSetInPoly = self::findMsbSet($poly); + $value <<= $msbSetInPoly - 1; + + while (self::findMsbSet($value) >= $msbSetInPoly) { + $value ^= $poly << (self::findMsbSet($value) - $msbSetInPoly); + } + + return $value; + } + + /** + * Finds and MSB set. + */ + private static function findMsbSet(int $value) : int + { + $numDigits = 0; + + while (0 !== $value) { + $value >>= 1; + ++$numDigits; + } + + return $numDigits; + } + + /** + * Embeds basic patterns into a matrix. + */ + private static function embedBasicPatterns(Version $version, ByteMatrix $matrix) : void + { + self::embedPositionDetectionPatternsAndSeparators($matrix); + self::embedDarkDotAtLeftBottomCorner($matrix); + self::maybeEmbedPositionAdjustmentPatterns($version, $matrix); + self::embedTimingPatterns($matrix); + } + + /** + * Embeds position detection patterns and separators into a byte matrix. + */ + private static function embedPositionDetectionPatternsAndSeparators(ByteMatrix $matrix) : void + { + $pdpWidth = count(self::POSITION_DETECTION_PATTERN[0]); + + self::embedPositionDetectionPattern(0, 0, $matrix); + self::embedPositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix); + self::embedPositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix); + + $hspWidth = 8; + + self::embedHorizontalSeparationPattern(0, $hspWidth - 1, $matrix); + self::embedHorizontalSeparationPattern($matrix->getWidth() - $hspWidth, $hspWidth - 1, $matrix); + self::embedHorizontalSeparationPattern(0, $matrix->getWidth() - $hspWidth, $matrix); + + $vspSize = 7; + + self::embedVerticalSeparationPattern($vspSize, 0, $matrix); + self::embedVerticalSeparationPattern($matrix->getHeight() - $vspSize - 1, 0, $matrix); + self::embedVerticalSeparationPattern($vspSize, $matrix->getHeight() - $vspSize, $matrix); + } + + /** + * Embeds a single position detection pattern into a byte matrix. + */ + private static function embedPositionDetectionPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 7; ++$y) { + for ($x = 0; $x < 7; ++$x) { + $matrix->set($xStart + $x, $yStart + $y, self::POSITION_DETECTION_PATTERN[$y][$x]); + } + } + } + + private static function removePositionDetectionPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 7; ++$y) { + for ($x = 0; $x < 7; ++$x) { + $matrix->set($xStart + $x, $yStart + $y, 0); + } + } + } + + /** + * Embeds a single horizontal separation pattern. + * + * @throws RuntimeException if a byte was already set + */ + private static function embedHorizontalSeparationPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($x = 0; $x < 8; $x++) { + if (-1 !== $matrix->get($xStart + $x, $yStart)) { + throw new RuntimeException('Byte already set'); + } + + $matrix->set($xStart + $x, $yStart, 0); + } + } + + /** + * Embeds a single vertical separation pattern. + * + * @throws RuntimeException if a byte was already set + */ + private static function embedVerticalSeparationPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 7; $y++) { + if (-1 !== $matrix->get($xStart, $yStart + $y)) { + throw new RuntimeException('Byte already set'); + } + + $matrix->set($xStart, $yStart + $y, 0); + } + } + + /** + * Embeds a dot at the left bottom corner. + * + * @throws RuntimeException if a byte was already set to 0 + */ + private static function embedDarkDotAtLeftBottomCorner(ByteMatrix $matrix) : void + { + if (0 === $matrix->get(8, $matrix->getHeight() - 8)) { + throw new RuntimeException('Byte already set to 0'); + } + + $matrix->set(8, $matrix->getHeight() - 8, 1); + } + + /** + * Embeds position adjustment patterns if required. + */ + private static function maybeEmbedPositionAdjustmentPatterns(Version $version, ByteMatrix $matrix) : void + { + if ($version->getVersionNumber() < 2) { + return; + } + + $index = $version->getVersionNumber() - 1; + + $coordinates = self::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[$index]; + $numCoordinates = count($coordinates); + + for ($i = 0; $i < $numCoordinates; ++$i) { + for ($j = 0; $j < $numCoordinates; ++$j) { + $y = $coordinates[$i]; + $x = $coordinates[$j]; + + if (null === $x || null === $y) { + continue; + } + + if (-1 === $matrix->get($x, $y)) { + self::embedPositionAdjustmentPattern($x - 2, $y - 2, $matrix); + } + } + } + } + + /** + * Embeds a single position adjustment pattern. + */ + private static function embedPositionAdjustmentPattern(int $xStart, int $yStart, ByteMatrix $matrix) : void + { + for ($y = 0; $y < 5; $y++) { + for ($x = 0; $x < 5; $x++) { + $matrix->set($xStart + $x, $yStart + $y, self::POSITION_ADJUSTMENT_PATTERN[$y][$x]); + } + } + } + + /** + * Embeds timing patterns into a matrix. + */ + private static function embedTimingPatterns(ByteMatrix $matrix) : void + { + $matrixWidth = $matrix->getWidth(); + + for ($i = 8; $i < $matrixWidth - 8; ++$i) { + $bit = ($i + 1) % 2; + + if (-1 === $matrix->get($i, 6)) { + $matrix->set($i, 6, $bit); + } + + if (-1 === $matrix->get(6, $i)) { + $matrix->set(6, $i, $bit); + } + } + } + + /** + * Embeds "dataBits" using "getMaskPattern". + * + * For debugging purposes, it skips masking process if "getMaskPattern" is -1. See 8.7 of JISX0510:2004 (p.38) for + * how to embed data bits. + * + * @throws WriterException if not all bits could be consumed + */ + private static function embedDataBits(BitArray $dataBits, int $maskPattern, ByteMatrix $matrix) : void + { + $bitIndex = 0; + $direction = -1; + + // Start from the right bottom cell. + $x = $matrix->getWidth() - 1; + $y = $matrix->getHeight() - 1; + + while ($x > 0) { + // Skip vertical timing pattern. + if (6 === $x) { + --$x; + } + + while ($y >= 0 && $y < $matrix->getHeight()) { + for ($i = 0; $i < 2; $i++) { + $xx = $x - $i; + + // Skip the cell if it's not empty. + if (-1 !== $matrix->get($xx, $y)) { + continue; + } + + if ($bitIndex < $dataBits->getSize()) { + $bit = $dataBits->get($bitIndex); + ++$bitIndex; + } else { + // Padding bit. If there is no bit left, we'll fill the + // left cells with 0, as described in 8.4.9 of + // JISX0510:2004 (p. 24). + $bit = false; + } + + // Skip masking if maskPattern is -1. + if (-1 !== $maskPattern && MaskUtil::getDataMaskBit($maskPattern, $xx, $y)) { + $bit = ! $bit; + } + + $matrix->set($xx, $y, (int) $bit); + } + + $y += $direction; + } + + $direction = -$direction; + $y += $direction; + $x -= 2; + } + + // All bits should be consumed + if ($dataBits->getSize() !== $bitIndex) { + throw new WriterException('Not all bits consumed (' . $bitIndex . ' out of ' . $dataBits->getSize() .')'); + } + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php b/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php new file mode 100644 index 0000000..c3398f4 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Encoder/QrCode.php @@ -0,0 +1,108 @@ +maskPattern = $maskPattern; + $this->matrix = $matrix; + } + + /** + * Gets the mode. + */ + public function getMode() : Mode + { + return $this->mode; + } + + /** + * Gets the EC level. + */ + public function getErrorCorrectionLevel() : ErrorCorrectionLevel + { + return $this->errorCorrectionLevel; + } + + /** + * Gets the version. + */ + public function getVersion() : Version + { + return $this->version; + } + + /** + * Gets the mask pattern. + */ + public function getMaskPattern() : int + { + return $this->maskPattern; + } + + public function getMatrix(): ByteMatrix + { + return $this->matrix; + } + + /** + * Validates whether a mask pattern is valid. + */ + public static function isValidMaskPattern(int $maskPattern) : bool + { + return $maskPattern > 0 && $maskPattern < self::NUM_MASK_PATTERNS; + } + + /** + * Returns a string representation of the QR code. + */ + public function __toString() : string + { + $result = "<<\n" + . ' mode: ' . $this->mode . "\n" + . ' ecLevel: ' . $this->errorCorrectionLevel . "\n" + . ' version: ' . $this->version . "\n" + . ' maskPattern: ' . $this->maskPattern . "\n"; + + if ($this->matrix === null) { + $result .= " matrix: null\n"; + } else { + $result .= " matrix:\n"; + $result .= $this->matrix; + } + + $result .= ">>\n"; + + return $result; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php b/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php new file mode 100644 index 0000000..6f70c20 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Exception/ExceptionInterface.php @@ -0,0 +1,10 @@ + 100) { + throw new Exception\InvalidArgumentException('Alpha must be between 0 and 100'); + } + } + + public function getAlpha() : int + { + return $this->alpha; + } + + public function getBaseColor() : ColorInterface + { + return $this->baseColor; + } + + public function toRgb() : Rgb + { + return $this->baseColor->toRgb(); + } + + public function toCmyk() : Cmyk + { + return $this->baseColor->toCmyk(); + } + + public function toGray() : Gray + { + return $this->baseColor->toGray(); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php b/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php new file mode 100644 index 0000000..d028210 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Color/Cmyk.php @@ -0,0 +1,82 @@ + 100) { + throw new Exception\InvalidArgumentException('Cyan must be between 0 and 100'); + } + + if ($magenta < 0 || $magenta > 100) { + throw new Exception\InvalidArgumentException('Magenta must be between 0 and 100'); + } + + if ($yellow < 0 || $yellow > 100) { + throw new Exception\InvalidArgumentException('Yellow must be between 0 and 100'); + } + + if ($black < 0 || $black > 100) { + throw new Exception\InvalidArgumentException('Black must be between 0 and 100'); + } + } + + public function getCyan() : int + { + return $this->cyan; + } + + public function getMagenta() : int + { + return $this->magenta; + } + + public function getYellow() : int + { + return $this->yellow; + } + + public function getBlack() : int + { + return $this->black; + } + + public function toRgb() : Rgb + { + $k = $this->black / 100; + $c = (-$k * $this->cyan + $k * 100 + $this->cyan) / 100; + $m = (-$k * $this->magenta + $k * 100 + $this->magenta) / 100; + $y = (-$k * $this->yellow + $k * 100 + $this->yellow) / 100; + + return new Rgb( + (int) (-$c * 255 + 255), + (int) (-$m * 255 + 255), + (int) (-$y * 255 + 255) + ); + } + + public function toCmyk() : Cmyk + { + return $this; + } + + public function toGray() : Gray + { + return $this->toRgb()->toGray(); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php b/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php new file mode 100644 index 0000000..b50d1ca --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Color/ColorInterface.php @@ -0,0 +1,22 @@ + 100) { + throw new Exception\InvalidArgumentException('Gray must be between 0 and 100'); + } + } + + public function getGray() : int + { + return $this->gray; + } + + public function toRgb() : Rgb + { + return new Rgb((int) ($this->gray * 2.55), (int) ($this->gray * 2.55), (int) ($this->gray * 2.55)); + } + + public function toCmyk() : Cmyk + { + return new Cmyk(0, 0, 0, 100 - $this->gray); + } + + public function toGray() : Gray + { + return $this; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php b/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php new file mode 100644 index 0000000..9e388da --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Color/Rgb.php @@ -0,0 +1,73 @@ + 255) { + throw new Exception\InvalidArgumentException('Red must be between 0 and 255'); + } + + if ($green < 0 || $green > 255) { + throw new Exception\InvalidArgumentException('Green must be between 0 and 255'); + } + + if ($blue < 0 || $blue > 255) { + throw new Exception\InvalidArgumentException('Blue must be between 0 and 255'); + } + } + + public function getRed() : int + { + return $this->red; + } + + public function getGreen() : int + { + return $this->green; + } + + public function getBlue() : int + { + return $this->blue; + } + + public function toRgb() : Rgb + { + return $this; + } + + public function toCmyk() : Cmyk + { + $c = 1 - ($this->red / 255); + $m = 1 - ($this->green / 255); + $y = 1 - ($this->blue / 255); + $k = min($c, $m, $y); + + if ($k === 0) { + return new Cmyk(0, 0, 0, 0); + } + + return new Cmyk( + (int) (100 * ($c - $k) / (1 - $k)), + (int) (100 * ($m - $k) / (1 - $k)), + (int) (100 * ($y - $k) / (1 - $k)), + (int) (100 * $k) + ); + } + + public function toGray() : Gray + { + return new Gray((int) (($this->red * 0.21 + $this->green * 0.71 + $this->blue * 0.07) / 2.55)); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php new file mode 100644 index 0000000..379e5c7 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/CompositeEye.php @@ -0,0 +1,26 @@ +externalEye->getExternalPath(); + } + + public function getInternalPath() : Path + { + return $this->internalEye->getInternalPath(); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php new file mode 100644 index 0000000..ab68f3c --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/EyeInterface.php @@ -0,0 +1,26 @@ +set($x, 0, 1); + $matrix->set($x, 6, 1); + } + + for ($y = 1; $y < 6; ++$y) { + $matrix->set(0, $y, 1); + $matrix->set(6, $y, 1); + } + + return $this->module->createPath($matrix)->translate(-3.5, -3.5); + } + + public function getInternalPath() : Path + { + $matrix = new ByteMatrix(3, 3); + + for ($x = 0; $x < 3; ++$x) { + for ($y = 0; $y < 3; ++$y) { + $matrix->set($x, $y, 1); + } + } + + return $this->module->createPath($matrix)->translate(-1.5, -1.5); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Eye/PointyEye.php b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/PointyEye.php new file mode 100644 index 0000000..39c7d23 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/PointyEye.php @@ -0,0 +1,56 @@ +move(-3.5, 3.5) + ->line(-3.5, 0) + ->ellipticArc(3.5, 3.5, 0, false, true, 0, -3.5) + ->line(3.5, -3.5) + ->line(3.5, 3.5) + ->close() + ->move(2.5, 0) + ->ellipticArc(2.5, 2.5, 0, false, true, 0, 2.5) + ->ellipticArc(2.5, 2.5, 0, false, true, -2.5, 0) + ->ellipticArc(2.5, 2.5, 0, false, true, 0, -2.5) + ->ellipticArc(2.5, 2.5, 0, false, true, 2.5, 0) + ->close() + ; + } + + public function getInternalPath() : Path + { + return (new Path()) + ->move(1.5, 0) + ->ellipticArc(1.5, 1.5, 0., false, true, 0., 1.5) + ->ellipticArc(1.5, 1.5, 0., false, true, -1.5, 0.) + ->ellipticArc(1.5, 1.5, 0., false, true, 0., -1.5) + ->ellipticArc(1.5, 1.5, 0., false, true, 1.5, 0.) + ->close() + ; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php new file mode 100644 index 0000000..735d326 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SimpleCircleEye.php @@ -0,0 +1,51 @@ +move(-3.5, -3.5) + ->line(3.5, -3.5) + ->line(3.5, 3.5) + ->line(-3.5, 3.5) + ->close() + ->move(-2.5, -2.5) + ->line(-2.5, 2.5) + ->line(2.5, 2.5) + ->line(2.5, -2.5) + ->close() + ; + } + + public function getInternalPath() : Path + { + return (new Path()) + ->move(1.5, 0) + ->ellipticArc(1.5, 1.5, 0., false, true, 0., 1.5) + ->ellipticArc(1.5, 1.5, 0., false, true, -1.5, 0.) + ->ellipticArc(1.5, 1.5, 0., false, true, 0., -1.5) + ->ellipticArc(1.5, 1.5, 0., false, true, 1.5, 0.) + ->close() + ; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php new file mode 100644 index 0000000..09bedfe --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Eye/SquareEye.php @@ -0,0 +1,50 @@ +move(-3.5, -3.5) + ->line(3.5, -3.5) + ->line(3.5, 3.5) + ->line(-3.5, 3.5) + ->close() + ->move(-2.5, -2.5) + ->line(-2.5, 2.5) + ->line(2.5, 2.5) + ->line(2.5, -2.5) + ->close() + ; + } + + public function getInternalPath() : Path + { + return (new Path()) + ->move(-1.5, -1.5) + ->line(1.5, -1.5) + ->line(1.5, 1.5) + ->line(-1.5, 1.5) + ->close() + ; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/GDLibRenderer.php b/vendor/bacon/bacon-qr-code/src/Renderer/GDLibRenderer.php new file mode 100644 index 0000000..7e6efc0 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/GDLibRenderer.php @@ -0,0 +1,237 @@ + + */ + private array $colors; + + public function __construct( + private int $size, + private int $margin = 4, + private string $imageFormat = 'png', + private int $compressionQuality = 9, + private ?Fill $fill = null + ) { + if (! extension_loaded('gd') || ! function_exists('gd_info')) { + throw new RuntimeException('You need to install the GD extension to use this back end'); + } + + if ($this->fill === null) { + $this->fill = Fill::default(); + } + if ($this->fill->hasGradientFill()) { + throw new InvalidArgumentException('GDLibRenderer does not support gradients'); + } + } + + /** + * @throws InvalidArgumentException if matrix width doesn't match height + */ + public function render(QrCode $qrCode): string + { + $matrix = $qrCode->getMatrix(); + $matrixSize = $matrix->getWidth(); + + if ($matrixSize !== $matrix->getHeight()) { + throw new InvalidArgumentException('Matrix must have the same width and height'); + } + + MatrixUtil::removePositionDetectionPatterns($matrix); + $this->newImage(); + $this->draw($matrix); + + return $this->renderImage(); + } + + private function newImage(): void + { + $img = imagecreatetruecolor($this->size, $this->size); + if ($img === false) { + throw new RuntimeException('Failed to create image of that size'); + } + + $this->image = $img; + imagealphablending($this->image, false); + imagesavealpha($this->image, true); + + + $bg = $this->getColor($this->fill->getBackgroundColor()); + imagefilledrectangle($this->image, 0, 0, $this->size, $this->size, $bg); + imagealphablending($this->image, true); + } + + private function draw(ByteMatrix $matrix): void + { + $matrixSize = $matrix->getWidth(); + + $pointsOnSide = $matrix->getWidth() + $this->margin * 2; + $pointInPx = $this->size / $pointsOnSide; + + $this->drawEye(0, 0, $pointInPx, $this->fill->getTopLeftEyeFill()); + $this->drawEye($matrixSize - 7, 0, $pointInPx, $this->fill->getTopRightEyeFill()); + $this->drawEye(0, $matrixSize - 7, $pointInPx, $this->fill->getBottomLeftEyeFill()); + + $rows = $matrix->getArray()->toArray(); + $color = $this->getColor($this->fill->getForegroundColor()); + for ($y = 0; $y < $matrixSize; $y += 1) { + for ($x = 0; $x < $matrixSize; $x += 1) { + if (! $rows[$y][$x]) { + continue; + } + + $points = $this->normalizePoints([ + ($this->margin + $x) * $pointInPx, ($this->margin + $y) * $pointInPx, + ($this->margin + $x + 1) * $pointInPx, ($this->margin + $y) * $pointInPx, + ($this->margin + $x + 1) * $pointInPx, ($this->margin + $y + 1) * $pointInPx, + ($this->margin + $x) * $pointInPx, ($this->margin + $y + 1) * $pointInPx, + ]); + imagefilledpolygon($this->image, $points, $color); + } + } + } + + private function drawEye(int $xOffset, int $yOffset, float $pointInPx, EyeFill $eyeFill): void + { + $internalColor = $this->getColor($eyeFill->inheritsInternalColor() + ? $this->fill->getForegroundColor() + : $eyeFill->getInternalColor()); + + $externalColor = $this->getColor($eyeFill->inheritsExternalColor() + ? $this->fill->getForegroundColor() + : $eyeFill->getExternalColor()); + + for ($y = 0; $y < 7; $y += 1) { + for ($x = 0; $x < 7; $x += 1) { + if ((($y === 1 || $y === 5) && $x > 0 && $x < 6) || (($x === 1 || $x === 5) && $y > 0 && $y < 6)) { + continue; + } + + $points = $this->normalizePoints([ + ($this->margin + $x + $xOffset) * $pointInPx, ($this->margin + $y + $yOffset) * $pointInPx, + ($this->margin + $x + $xOffset + 1) * $pointInPx, ($this->margin + $y + $yOffset) * $pointInPx, + ($this->margin + $x + $xOffset + 1) * $pointInPx, ($this->margin + $y + $yOffset + 1) * $pointInPx, + ($this->margin + $x + $xOffset) * $pointInPx, ($this->margin + $y + $yOffset + 1) * $pointInPx, + ]); + + if ($y > 1 && $y < 5 && $x > 1 && $x < 5) { + imagefilledpolygon($this->image, $points, $internalColor); + } else { + imagefilledpolygon($this->image, $points, $externalColor); + } + } + } + } + + /** + * Normalize points will trim right and bottom line by 1 pixel. + * Otherwise pixels of neighbors are overlapping which leads to issue with transparency and small QR codes. + */ + private function normalizePoints(array $points): array + { + $maxX = $maxY = 0; + for ($i = 0; $i < count($points); $i += 2) { + // Do manual round as GD just removes decimal part + $points[$i] = $newX = round($points[$i]); + $points[$i + 1] = $newY = round($points[$i + 1]); + + $maxX = max($maxX, $newX); + $maxY = max($maxY, $newY); + } + + // Do trimming only if there are 4 points (8 coordinates), assumes this is square. + + for ($i = 0; $i < count($points); $i += 2) { + $points[$i] = min($points[$i], $maxX - 1); + $points[$i + 1] = min($points[$i + 1], $maxY - 1); + } + + return $points; + } + + private function renderImage(): string + { + ob_start(); + $quality = $this->compressionQuality; + switch ($this->imageFormat) { + case 'png': + if ($quality > 9 || $quality < 0) { + $quality = 9; + } + imagepng($this->image, null, $quality); + break; + + case 'gif': + imagegif($this->image, null); + break; + + case 'jpeg': + case 'jpg': + if ($quality > 100 || $quality < 0) { + $quality = 85; + } + imagejpeg($this->image, null, $quality); + break; + default: + ob_end_clean(); + throw new InvalidArgumentException( + 'Supported image formats are jpeg, png and gif, got: ' . $this->imageFormat + ); + } + + $this->colors = []; + $this->image = null; + + return ob_get_clean(); + } + + private function getColor(ColorInterface $color): int + { + $alpha = 100; + + if ($color instanceof Alpha) { + $alpha = $color->getAlpha(); + $color = $color->getBaseColor(); + } + + $rgb = $color->toRgb(); + + $colorKey = sprintf('%02X%02X%02X%02X', $rgb->getRed(), $rgb->getGreen(), $rgb->getBlue(), $alpha); + + if (! isset($this->colors[$colorKey])) { + $colorId = imagecolorallocatealpha( + $this->image, + $rgb->getRed(), + $rgb->getGreen(), + $rgb->getBlue(), + (int)((100 - $alpha) / 100 * 127) // Alpha for GD is in range 0 (opaque) - 127 (transparent) + ); + + if ($colorId === false) { + throw new RuntimeException('Failed to create color: #' . $colorKey); + } + + $this->colors[$colorKey] = $colorId; + } + + return $this->colors[$colorKey]; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php b/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php new file mode 100644 index 0000000..4269456 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Image/EpsImageBackEnd.php @@ -0,0 +1,373 @@ +eps = "%!PS-Adobe-3.0 EPSF-3.0\n" + . "%%Creator: BaconQrCode\n" + . sprintf("%%%%BoundingBox: 0 0 %d %d \n", $size, $size) + . "%%BeginProlog\n" + . "save\n" + . "50 dict begin\n" + . "/q { gsave } bind def\n" + . "/Q { grestore } bind def\n" + . "/s { scale } bind def\n" + . "/t { translate } bind def\n" + . "/r { rotate } bind def\n" + . "/n { newpath } bind def\n" + . "/m { moveto } bind def\n" + . "/l { lineto } bind def\n" + . "/c { curveto } bind def\n" + . "/z { closepath } bind def\n" + . "/f { eofill } bind def\n" + . "/rgb { setrgbcolor } bind def\n" + . "/cmyk { setcmykcolor } bind def\n" + . "/gray { setgray } bind def\n" + . "%%EndProlog\n" + . "1 -1 s\n" + . sprintf("0 -%d t\n", $size); + + if ($backgroundColor instanceof Alpha && 0 === $backgroundColor->getAlpha()) { + return; + } + + $this->eps .= wordwrap( + '0 0 m' + . sprintf(' %s 0 l', (string) $size) + . sprintf(' %s %s l', (string) $size, (string) $size) + . sprintf(' 0 %s l', (string) $size) + . ' z' + . ' ' .$this->getColorSetString($backgroundColor) . " f\n", + 75, + "\n " + ); + } + + public function scale(float $size) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= sprintf("%1\$s %1\$s s\n", round($size, self::PRECISION)); + } + + public function translate(float $x, float $y) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= sprintf("%s %s t\n", round($x, self::PRECISION), round($y, self::PRECISION)); + } + + public function rotate(int $degrees) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= sprintf("%d r\n", $degrees); + } + + public function push() : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= "q\n"; + } + + public function pop() : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= "Q\n"; + } + + public function drawPathWithColor(Path $path, ColorInterface $color) : void + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $fromX = 0; + $fromY = 0; + $this->eps .= wordwrap( + 'n ' + . $this->drawPathOperations($path, $fromX, $fromY) + . ' ' . $this->getColorSetString($color) . " f\n", + 75, + "\n " + ); + } + + public function drawPathWithGradient( + Path $path, + Gradient $gradient, + float $x, + float $y, + float $width, + float $height + ) : void { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $fromX = 0; + $fromY = 0; + $this->eps .= wordwrap( + 'q n ' . $this->drawPathOperations($path, $fromX, $fromY) . "\n", + 75, + "\n " + ); + + $this->createGradientFill($gradient, $x, $y, $width, $height); + } + + public function done() : string + { + if (null === $this->eps) { + throw new RuntimeException('No image has been started'); + } + + $this->eps .= "%%TRAILER\nend restore\n%%EOF"; + $blob = $this->eps; + $this->eps = null; + + return $blob; + } + + private function drawPathOperations(Iterable $ops, &$fromX, &$fromY) : string + { + $pathData = []; + + foreach ($ops as $op) { + switch (true) { + case $op instanceof Move: + $fromX = $toX = round($op->getX(), self::PRECISION); + $fromY = $toY = round($op->getY(), self::PRECISION); + $pathData[] = sprintf('%s %s m', $toX, $toY); + break; + + case $op instanceof Line: + $fromX = $toX = round($op->getX(), self::PRECISION); + $fromY = $toY = round($op->getY(), self::PRECISION); + $pathData[] = sprintf('%s %s l', $toX, $toY); + break; + + case $op instanceof EllipticArc: + $pathData[] = $this->drawPathOperations($op->toCurves($fromX, $fromY), $fromX, $fromY); + break; + + case $op instanceof Curve: + $x1 = round($op->getX1(), self::PRECISION); + $y1 = round($op->getY1(), self::PRECISION); + $x2 = round($op->getX2(), self::PRECISION); + $y2 = round($op->getY2(), self::PRECISION); + $fromX = $x3 = round($op->getX3(), self::PRECISION); + $fromY = $y3 = round($op->getY3(), self::PRECISION); + $pathData[] = sprintf('%s %s %s %s %s %s c', $x1, $y1, $x2, $y2, $x3, $y3); + break; + + case $op instanceof Close: + $pathData[] = 'z'; + break; + + default: + throw new RuntimeException('Unexpected draw operation: ' . get_class($op)); + } + } + + return implode(' ', $pathData); + } + + private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : void + { + $startColor = $gradient->getStartColor(); + $endColor = $gradient->getEndColor(); + + if ($startColor instanceof Alpha) { + $startColor = $startColor->getBaseColor(); + } + + $startColorType = get_class($startColor); + + if (! in_array($startColorType, [Rgb::class, Cmyk::class, Gray::class])) { + $startColorType = Cmyk::class; + $startColor = $startColor->toCmyk(); + } + + if (get_class($endColor) !== $startColorType) { + switch ($startColorType) { + case Cmyk::class: + $endColor = $endColor->toCmyk(); + break; + + case Rgb::class: + $endColor = $endColor->toRgb(); + break; + + case Gray::class: + $endColor = $endColor->toGray(); + break; + } + } + + $this->eps .= "eoclip\n<<\n"; + + if ($gradient->getType() === GradientType::RADIAL()) { + $this->eps .= " /ShadingType 3\n"; + } else { + $this->eps .= " /ShadingType 2\n"; + } + + $this->eps .= " /Extend [ true true ]\n" + . " /AntiAlias true\n"; + + switch ($startColorType) { + case Cmyk::class: + $this->eps .= " /ColorSpace /DeviceCMYK\n"; + break; + + case Rgb::class: + $this->eps .= " /ColorSpace /DeviceRGB\n"; + break; + + case Gray::class: + $this->eps .= " /ColorSpace /DeviceGray\n"; + break; + } + + switch ($gradient->getType()) { + case GradientType::HORIZONTAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x + $width, self::PRECISION), + round($y, self::PRECISION) + ); + break; + + case GradientType::VERTICAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x, self::PRECISION), + round($y + $height, self::PRECISION) + ); + break; + + case GradientType::DIAGONAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y, self::PRECISION), + round($x + $width, self::PRECISION), + round($y + $height, self::PRECISION) + ); + break; + + case GradientType::INVERSE_DIAGONAL(): + $this->eps .= sprintf( + " /Coords [ %s %s %s %s ]\n", + round($x, self::PRECISION), + round($y + $height, self::PRECISION), + round($x + $width, self::PRECISION), + round($y, self::PRECISION) + ); + break; + + case GradientType::RADIAL(): + $centerX = ($x + $width) / 2; + $centerY = ($y + $height) / 2; + + $this->eps .= sprintf( + " /Coords [ %s %s 0 %s %s %s ]\n", + round($centerX, self::PRECISION), + round($centerY, self::PRECISION), + round($centerX, self::PRECISION), + round($centerY, self::PRECISION), + round(max($width, $height) / 2, self::PRECISION) + ); + break; + } + + $this->eps .= " /Function\n" + . " <<\n" + . " /FunctionType 2\n" + . " /Domain [ 0 1 ]\n" + . sprintf(" /C0 [ %s ]\n", $this->getColorString($startColor)) + . sprintf(" /C1 [ %s ]\n", $this->getColorString($endColor)) + . " /N 1\n" + . " >>\n>>\nshfill\nQ\n"; + } + + private function getColorSetString(ColorInterface $color) : string + { + if ($color instanceof Rgb) { + return $this->getColorString($color) . ' rgb'; + } + + if ($color instanceof Cmyk) { + return $this->getColorString($color) . ' cmyk'; + } + + if ($color instanceof Gray) { + return $this->getColorString($color) . ' gray'; + } + + return $this->getColorSetString($color->toCmyk()); + } + + private function getColorString(ColorInterface $color) : string + { + if ($color instanceof Rgb) { + return sprintf('%s %s %s', $color->getRed() / 255, $color->getGreen() / 255, $color->getBlue() / 255); + } + + if ($color instanceof Cmyk) { + return sprintf( + '%s %s %s %s', + $color->getCyan() / 100, + $color->getMagenta() / 100, + $color->getYellow() / 100, + $color->getBlack() / 100 + ); + } + + if ($color instanceof Gray) { + return sprintf('%s', $color->getGray() / 100); + } + + return $this->getColorString($color->toCmyk()); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php b/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php new file mode 100644 index 0000000..0935819 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Image/ImageBackEndInterface.php @@ -0,0 +1,87 @@ +imageFormat = $imageFormat; + $this->compressionQuality = $compressionQuality; + } + + public function new(int $size, ColorInterface $backgroundColor) : void + { + $this->image = new Imagick(); + $this->image->newImage($size, $size, $this->getColorPixel($backgroundColor)); + $this->image->setImageFormat($this->imageFormat); + $this->image->setCompressionQuality($this->compressionQuality); + $this->draw = new ImagickDraw(); + $this->gradientCount = 0; + $this->matrices = [new TransformationMatrix()]; + $this->matrixIndex = 0; + } + + public function scale(float $size) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->scale($size, $size); + $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex] + ->multiply(TransformationMatrix::scale($size)); + } + + public function translate(float $x, float $y) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->translate($x, $y); + $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex] + ->multiply(TransformationMatrix::translate($x, $y)); + } + + public function rotate(int $degrees) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->rotate($degrees); + $this->matrices[$this->matrixIndex] = $this->matrices[$this->matrixIndex] + ->multiply(TransformationMatrix::rotate($degrees)); + } + + public function push() : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->push(); + $this->matrices[++$this->matrixIndex] = $this->matrices[$this->matrixIndex - 1]; + } + + public function pop() : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->pop(); + unset($this->matrices[$this->matrixIndex--]); + } + + public function drawPathWithColor(Path $path, ColorInterface $color) : void + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->setFillColor($this->getColorPixel($color)); + $this->drawPath($path); + } + + public function drawPathWithGradient( + Path $path, + Gradient $gradient, + float $x, + float $y, + float $width, + float $height + ) : void { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->draw->setFillPatternURL('#' . $this->createGradientFill($gradient, $x, $y, $width, $height)); + $this->drawPath($path); + } + + public function done() : string + { + if (null === $this->draw) { + throw new RuntimeException('No image has been started'); + } + + $this->image->drawImage($this->draw); + $blob = $this->image->getImageBlob(); + $this->draw->clear(); + $this->image->clear(); + $this->draw = null; + $this->image = null; + $this->gradientCount = null; + + return $blob; + } + + private function drawPath(Path $path) : void + { + $this->draw->pathStart(); + + foreach ($path as $op) { + switch (true) { + case $op instanceof Move: + $this->draw->pathMoveToAbsolute($op->getX(), $op->getY()); + break; + + case $op instanceof Line: + $this->draw->pathLineToAbsolute($op->getX(), $op->getY()); + break; + + case $op instanceof EllipticArc: + $this->draw->pathEllipticArcAbsolute( + $op->getXRadius(), + $op->getYRadius(), + $op->getXAxisAngle(), + $op->isLargeArc(), + $op->isSweep(), + $op->getX(), + $op->getY() + ); + break; + + case $op instanceof Curve: + $this->draw->pathCurveToAbsolute( + $op->getX1(), + $op->getY1(), + $op->getX2(), + $op->getY2(), + $op->getX3(), + $op->getY3() + ); + break; + + case $op instanceof Close: + $this->draw->pathClose(); + break; + + default: + throw new RuntimeException('Unexpected draw operation: ' . get_class($op)); + } + } + + $this->draw->pathFinish(); + } + + private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : string + { + list($width, $height) = $this->matrices[$this->matrixIndex]->apply($width, $height); + + $startColor = $this->getColorPixel($gradient->getStartColor())->getColorAsString(); + $endColor = $this->getColorPixel($gradient->getEndColor())->getColorAsString(); + $gradientImage = new Imagick(); + + switch ($gradient->getType()) { + case GradientType::HORIZONTAL(): + $gradientImage->newPseudoImage((int) $height, (int) $width, sprintf( + 'gradient:%s-%s', + $startColor, + $endColor + )); + $gradientImage->rotateImage('transparent', -90); + break; + + case GradientType::VERTICAL(): + $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf( + 'gradient:%s-%s', + $startColor, + $endColor + )); + break; + + case GradientType::DIAGONAL(): + case GradientType::INVERSE_DIAGONAL(): + $gradientImage->newPseudoImage((int) ($width * sqrt(2)), (int) ($height * sqrt(2)), sprintf( + 'gradient:%s-%s', + $startColor, + $endColor + )); + + if (GradientType::DIAGONAL() === $gradient->getType()) { + $gradientImage->rotateImage('transparent', -45); + } else { + $gradientImage->rotateImage('transparent', -135); + } + + $rotatedWidth = $gradientImage->getImageWidth(); + $rotatedHeight = $gradientImage->getImageHeight(); + + $gradientImage->setImagePage($rotatedWidth, $rotatedHeight, 0, 0); + $gradientImage->cropImage( + intdiv($rotatedWidth, 2) - 2, + intdiv($rotatedHeight, 2) - 2, + intdiv($rotatedWidth, 4) + 1, + intdiv($rotatedWidth, 4) + 1 + ); + break; + + case GradientType::RADIAL(): + $gradientImage->newPseudoImage((int) $width, (int) $height, sprintf( + 'radial-gradient:%s-%s', + $startColor, + $endColor + )); + break; + } + + $id = sprintf('g%d', ++$this->gradientCount); + $this->draw->pushPattern($id, 0, 0, $width, $height); + $this->draw->composite(Imagick::COMPOSITE_COPY, 0, 0, $width, $height, $gradientImage); + $this->draw->popPattern(); + return $id; + } + + private function getColorPixel(ColorInterface $color) : ImagickPixel + { + $alpha = 100; + + if ($color instanceof Alpha) { + $alpha = $color->getAlpha(); + $color = $color->getBaseColor(); + } + + if ($color instanceof Rgb) { + return new ImagickPixel(sprintf( + 'rgba(%d, %d, %d, %F)', + $color->getRed(), + $color->getGreen(), + $color->getBlue(), + $alpha / 100 + )); + } + + if ($color instanceof Cmyk) { + return new ImagickPixel(sprintf( + 'cmyka(%d, %d, %d, %d, %F)', + $color->getCyan(), + $color->getMagenta(), + $color->getYellow(), + $color->getBlack(), + $alpha / 100 + )); + } + + if ($color instanceof Gray) { + return new ImagickPixel(sprintf( + 'graya(%d%%, %F)', + $color->getGray(), + $alpha / 100 + )); + } + + return $this->getColorPixel(new Alpha($alpha, $color->toRgb())); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php b/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php new file mode 100644 index 0000000..44d014e --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Image/SvgImageBackEnd.php @@ -0,0 +1,363 @@ +xmlWriter = new XMLWriter(); + $this->xmlWriter->openMemory(); + + $this->xmlWriter->startDocument('1.0', 'UTF-8'); + $this->xmlWriter->startElement('svg'); + $this->xmlWriter->writeAttribute('xmlns', 'http://www.w3.org/2000/svg'); + $this->xmlWriter->writeAttribute('version', '1.1'); + $this->xmlWriter->writeAttribute('width', (string) $size); + $this->xmlWriter->writeAttribute('height', (string) $size); + $this->xmlWriter->writeAttribute('viewBox', '0 0 '. $size . ' ' . $size); + + $this->gradientCount = 0; + $this->currentStack = 0; + $this->stack[0] = 0; + + $alpha = 1; + + if ($backgroundColor instanceof Alpha) { + $alpha = $backgroundColor->getAlpha() / 100; + } + + if (0 === $alpha) { + return; + } + + $this->xmlWriter->startElement('rect'); + $this->xmlWriter->writeAttribute('x', '0'); + $this->xmlWriter->writeAttribute('y', '0'); + $this->xmlWriter->writeAttribute('width', (string) $size); + $this->xmlWriter->writeAttribute('height', (string) $size); + $this->xmlWriter->writeAttribute('fill', $this->getColorString($backgroundColor)); + + if ($alpha < 1) { + $this->xmlWriter->writeAttribute('fill-opacity', (string) $alpha); + } + + $this->xmlWriter->endElement(); + } + + public function scale(float $size) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->xmlWriter->writeAttribute( + 'transform', + sprintf(self::SCALE_FORMAT, round($size, self::PRECISION)) + ); + ++$this->stack[$this->currentStack]; + } + + public function translate(float $x, float $y) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->xmlWriter->writeAttribute( + 'transform', + sprintf(self::TRANSLATE_FORMAT, round($x, self::PRECISION), round($y, self::PRECISION)) + ); + ++$this->stack[$this->currentStack]; + } + + public function rotate(int $degrees) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->xmlWriter->writeAttribute('transform', sprintf('rotate(%d)', $degrees)); + ++$this->stack[$this->currentStack]; + } + + public function push() : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $this->xmlWriter->startElement('g'); + $this->stack[] = 1; + ++$this->currentStack; + } + + public function pop() : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + for ($i = 0; $i < $this->stack[$this->currentStack]; ++$i) { + $this->xmlWriter->endElement(); + } + + array_pop($this->stack); + --$this->currentStack; + } + + public function drawPathWithColor(Path $path, ColorInterface $color) : void + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $alpha = 1; + + if ($color instanceof Alpha) { + $alpha = $color->getAlpha() / 100; + } + + $this->startPathElement($path); + $this->xmlWriter->writeAttribute('fill', $this->getColorString($color)); + + if ($alpha < 1) { + $this->xmlWriter->writeAttribute('fill-opacity', (string) $alpha); + } + + $this->xmlWriter->endElement(); + } + + public function drawPathWithGradient( + Path $path, + Gradient $gradient, + float $x, + float $y, + float $width, + float $height + ) : void { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + $gradientId = $this->createGradientFill($gradient, $x, $y, $width, $height); + $this->startPathElement($path); + $this->xmlWriter->writeAttribute('fill', 'url(#' . $gradientId . ')'); + $this->xmlWriter->endElement(); + } + + public function done() : string + { + if (null === $this->xmlWriter) { + throw new RuntimeException('No image has been started'); + } + + foreach ($this->stack as $openElements) { + for ($i = $openElements; $i > 0; --$i) { + $this->xmlWriter->endElement(); + } + } + + $this->xmlWriter->endDocument(); + $blob = $this->xmlWriter->outputMemory(true); + $this->xmlWriter = null; + $this->stack = null; + $this->currentStack = null; + $this->gradientCount = null; + + return $blob; + } + + private function startPathElement(Path $path) : void + { + $pathData = []; + + foreach ($path as $op) { + switch (true) { + case $op instanceof Move: + $pathData[] = sprintf( + 'M%s %s', + round($op->getX(), self::PRECISION), + round($op->getY(), self::PRECISION) + ); + break; + + case $op instanceof Line: + $pathData[] = sprintf( + 'L%s %s', + round($op->getX(), self::PRECISION), + round($op->getY(), self::PRECISION) + ); + break; + + case $op instanceof EllipticArc: + $pathData[] = sprintf( + 'A%s %s %s %u %u %s %s', + round($op->getXRadius(), self::PRECISION), + round($op->getYRadius(), self::PRECISION), + round($op->getXAxisAngle(), self::PRECISION), + $op->isLargeArc(), + $op->isSweep(), + round($op->getX(), self::PRECISION), + round($op->getY(), self::PRECISION) + ); + break; + + case $op instanceof Curve: + $pathData[] = sprintf( + 'C%s %s %s %s %s %s', + round($op->getX1(), self::PRECISION), + round($op->getY1(), self::PRECISION), + round($op->getX2(), self::PRECISION), + round($op->getY2(), self::PRECISION), + round($op->getX3(), self::PRECISION), + round($op->getY3(), self::PRECISION) + ); + break; + + case $op instanceof Close: + $pathData[] = 'Z'; + break; + + default: + throw new RuntimeException('Unexpected draw operation: ' . get_class($op)); + } + } + + $this->xmlWriter->startElement('path'); + $this->xmlWriter->writeAttribute('fill-rule', 'evenodd'); + $this->xmlWriter->writeAttribute('d', implode('', $pathData)); + } + + private function createGradientFill(Gradient $gradient, float $x, float $y, float $width, float $height) : string + { + $this->xmlWriter->startElement('defs'); + + $startColor = $gradient->getStartColor(); + $endColor = $gradient->getEndColor(); + + if ($gradient->getType() === GradientType::RADIAL()) { + $this->xmlWriter->startElement('radialGradient'); + } else { + $this->xmlWriter->startElement('linearGradient'); + } + + $this->xmlWriter->writeAttribute('gradientUnits', 'userSpaceOnUse'); + + switch ($gradient->getType()) { + case GradientType::HORIZONTAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION)); + break; + + case GradientType::VERTICAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION)); + break; + + case GradientType::DIAGONAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y + $height, self::PRECISION)); + break; + + case GradientType::INVERSE_DIAGONAL(): + $this->xmlWriter->writeAttribute('x1', (string) round($x, self::PRECISION)); + $this->xmlWriter->writeAttribute('y1', (string) round($y + $height, self::PRECISION)); + $this->xmlWriter->writeAttribute('x2', (string) round($x + $width, self::PRECISION)); + $this->xmlWriter->writeAttribute('y2', (string) round($y, self::PRECISION)); + break; + + case GradientType::RADIAL(): + $this->xmlWriter->writeAttribute('cx', (string) round(($x + $width) / 2, self::PRECISION)); + $this->xmlWriter->writeAttribute('cy', (string) round(($y + $height) / 2, self::PRECISION)); + $this->xmlWriter->writeAttribute('r', (string) round(max($width, $height) / 2, self::PRECISION)); + break; + } + + $toBeHashed = $this->getColorString($startColor) . $this->getColorString($endColor) . $gradient->getType(); + if ($startColor instanceof Alpha) { + $toBeHashed .= (string) $startColor->getAlpha(); + } + $id = sprintf('g%d-%s', ++$this->gradientCount, hash('xxh64', $toBeHashed)); + $this->xmlWriter->writeAttribute('id', $id); + + $this->xmlWriter->startElement('stop'); + $this->xmlWriter->writeAttribute('offset', '0%'); + $this->xmlWriter->writeAttribute('stop-color', $this->getColorString($startColor)); + + if ($startColor instanceof Alpha) { + $this->xmlWriter->writeAttribute('stop-opacity', (string) $startColor->getAlpha()); + } + + $this->xmlWriter->endElement(); + + $this->xmlWriter->startElement('stop'); + $this->xmlWriter->writeAttribute('offset', '100%'); + $this->xmlWriter->writeAttribute('stop-color', $this->getColorString($endColor)); + + if ($endColor instanceof Alpha) { + $this->xmlWriter->writeAttribute('stop-opacity', (string) $endColor->getAlpha()); + } + + $this->xmlWriter->endElement(); + + $this->xmlWriter->endElement(); + $this->xmlWriter->endElement(); + + return $id; + } + + private function getColorString(ColorInterface $color) : string + { + $color = $color->toRgb(); + + return sprintf( + '#%02x%02x%02x', + $color->getRed(), + $color->getGreen(), + $color->getBlue() + ); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php b/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php new file mode 100644 index 0000000..9b435a0 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Image/TransformationMatrix.php @@ -0,0 +1,68 @@ +values = [1, 0, 0, 1, 0, 0]; + } + + public function multiply(self $other) : self + { + $matrix = new self(); + $matrix->values[0] = $this->values[0] * $other->values[0] + $this->values[2] * $other->values[1]; + $matrix->values[1] = $this->values[1] * $other->values[0] + $this->values[3] * $other->values[1]; + $matrix->values[2] = $this->values[0] * $other->values[2] + $this->values[2] * $other->values[3]; + $matrix->values[3] = $this->values[1] * $other->values[2] + $this->values[3] * $other->values[3]; + $matrix->values[4] = $this->values[0] * $other->values[4] + $this->values[2] * $other->values[5] + + $this->values[4]; + $matrix->values[5] = $this->values[1] * $other->values[4] + $this->values[3] * $other->values[5] + + $this->values[5]; + + return $matrix; + } + + public static function scale(float $size) : self + { + $matrix = new self(); + $matrix->values = [$size, 0, 0, $size, 0, 0]; + return $matrix; + } + + public static function translate(float $x, float $y) : self + { + $matrix = new self(); + $matrix->values = [1, 0, 0, 1, $x, $y]; + return $matrix; + } + + public static function rotate(int $degrees) : self + { + $matrix = new self(); + $rad = deg2rad($degrees); + $matrix->values = [cos($rad), sin($rad), -sin($rad), cos($rad), 0, 0]; + return $matrix; + } + + + /** + * Applies this matrix onto a point and returns the resulting viewport point. + * + * @return float[] + */ + public function apply(float $x, float $y) : array + { + return [ + $x * $this->values[0] + $y * $this->values[2] + $this->values[4], + $x * $this->values[1] + $y * $this->values[3] + $this->values[5], + ]; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php b/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php new file mode 100644 index 0000000..0d33303 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/ImageRenderer.php @@ -0,0 +1,150 @@ +rendererStyle->getSize(); + $margin = $this->rendererStyle->getMargin(); + $matrix = $qrCode->getMatrix(); + $matrixSize = $matrix->getWidth(); + + if ($matrixSize !== $matrix->getHeight()) { + throw new InvalidArgumentException('Matrix must have the same width and height'); + } + + $totalSize = $matrixSize + ($margin * 2); + $moduleSize = $size / $totalSize; + $fill = $this->rendererStyle->getFill(); + + $this->imageBackEnd->new($size, $fill->getBackgroundColor()); + $this->imageBackEnd->scale((float) $moduleSize); + $this->imageBackEnd->translate((float) $margin, (float) $margin); + + $module = $this->rendererStyle->getModule(); + $moduleMatrix = clone $matrix; + MatrixUtil::removePositionDetectionPatterns($moduleMatrix); + $modulePath = $this->drawEyes($matrixSize, $module->createPath($moduleMatrix)); + + if ($fill->hasGradientFill()) { + $this->imageBackEnd->drawPathWithGradient( + $modulePath, + $fill->getForegroundGradient(), + 0, + 0, + $matrixSize, + $matrixSize + ); + } else { + $this->imageBackEnd->drawPathWithColor($modulePath, $fill->getForegroundColor()); + } + + return $this->imageBackEnd->done(); + } + + private function drawEyes(int $matrixSize, Path $modulePath) : Path + { + $fill = $this->rendererStyle->getFill(); + + $eye = $this->rendererStyle->getEye(); + $externalPath = $eye->getExternalPath(); + $internalPath = $eye->getInternalPath(); + + $modulePath = $this->drawEye( + $externalPath, + $internalPath, + $fill->getTopLeftEyeFill(), + 3.5, + 3.5, + 0, + $modulePath + ); + $modulePath = $this->drawEye( + $externalPath, + $internalPath, + $fill->getTopRightEyeFill(), + $matrixSize - 3.5, + 3.5, + 90, + $modulePath + ); + $modulePath = $this->drawEye( + $externalPath, + $internalPath, + $fill->getBottomLeftEyeFill(), + 3.5, + $matrixSize - 3.5, + -90, + $modulePath + ); + + return $modulePath; + } + + private function drawEye( + Path $externalPath, + Path $internalPath, + EyeFill $fill, + float $xTranslation, + float $yTranslation, + int $rotation, + Path $modulePath + ) : Path { + if ($fill->inheritsBothColors()) { + return $modulePath + ->append( + $externalPath->rotate($rotation)->translate($xTranslation, $yTranslation) + ) + ->append( + $internalPath->rotate($rotation)->translate($xTranslation, $yTranslation) + ); + } + + $this->imageBackEnd->push(); + $this->imageBackEnd->translate($xTranslation, $yTranslation); + + if (0 !== $rotation) { + $this->imageBackEnd->rotate($rotation); + } + + if ($fill->inheritsExternalColor()) { + $modulePath = $modulePath->append( + $externalPath->rotate($rotation)->translate($xTranslation, $yTranslation) + ); + } else { + $this->imageBackEnd->drawPathWithColor($externalPath, $fill->getExternalColor()); + } + + if ($fill->inheritsInternalColor()) { + $modulePath = $modulePath->append( + $internalPath->rotate($rotation)->translate($xTranslation, $yTranslation) + ); + } else { + $this->imageBackEnd->drawPathWithColor($internalPath, $fill->getInternalColor()); + } + + $this->imageBackEnd->pop(); + + return $modulePath; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php b/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php new file mode 100644 index 0000000..c5d5c6f --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Module/DotsModule.php @@ -0,0 +1,56 @@ + 1) { + throw new InvalidArgumentException('Size must between 0 (exclusive) and 1 (inclusive)'); + } + } + + public function createPath(ByteMatrix $matrix) : Path + { + $width = $matrix->getWidth(); + $height = $matrix->getHeight(); + $path = new Path(); + $halfSize = $this->size / 2; + $margin = (1 - $this->size) / 2; + + for ($y = 0; $y < $height; ++$y) { + for ($x = 0; $x < $width; ++$x) { + if (! $matrix->get($x, $y)) { + continue; + } + + $pathX = $x + $margin; + $pathY = $y + $margin; + + $path = $path + ->move($pathX + $this->size, $pathY + $halfSize) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $halfSize, $pathY + $this->size) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX, $pathY + $halfSize) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $halfSize, $pathY) + ->ellipticArc($halfSize, $halfSize, 0, false, true, $pathX + $this->size, $pathY + $halfSize) + ->close() + ; + } + } + + return $path; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php b/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php new file mode 100644 index 0000000..141d66c --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/Edge.php @@ -0,0 +1,82 @@ + + */ + private array $points = []; + + /** + * @var array|null + */ + private ?array $simplifiedPoints = null; + + private int $minX = PHP_INT_MAX; + + private int $minY = PHP_INT_MAX; + + private int $maxX = -1; + + private int $maxY = -1; + + public function __construct(private readonly bool $positive) + { + } + + public function addPoint(int $x, int $y) : void + { + $this->points[] = [$x, $y]; + $this->minX = min($this->minX, $x); + $this->minY = min($this->minY, $y); + $this->maxX = max($this->maxX, $x); + $this->maxY = max($this->maxY, $y); + } + + public function isPositive() : bool + { + return $this->positive; + } + + /** + * @return array + */ + public function getPoints() : array + { + return $this->points; + } + + public function getMaxX() : int + { + return $this->maxX; + } + + public function getSimplifiedPoints() : array + { + if (null !== $this->simplifiedPoints) { + return $this->simplifiedPoints; + } + + $points = []; + $length = count($this->points); + + for ($i = 0; $i < $length; ++$i) { + $previousPoint = $this->points[(0 === $i ? $length : $i) - 1]; + $nextPoint = $this->points[($length - 1 === $i ? -1 : $i) + 1]; + $currentPoint = $this->points[$i]; + + if (($previousPoint[0] === $currentPoint[0] && $currentPoint[0] === $nextPoint[0]) + || ($previousPoint[1] === $currentPoint[1] && $currentPoint[1] === $nextPoint[1]) + ) { + continue; + } + + $points[] = $currentPoint; + } + + return $this->simplifiedPoints = $points; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php b/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php new file mode 100644 index 0000000..01f692c --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Module/EdgeIterator/EdgeIterator.php @@ -0,0 +1,160 @@ +bytes = iterator_to_array($matrix->getBytes()); + $this->size = count($this->bytes); + $this->width = $matrix->getWidth(); + $this->height = $matrix->getHeight(); + } + + /** + * @return Traversable + */ + public function getIterator() : Traversable + { + $originalBytes = $this->bytes; + $point = $this->findNext(0, 0); + + while (null !== $point) { + $edge = $this->findEdge($point[0], $point[1]); + $this->xorEdge($edge); + + yield $edge; + + $point = $this->findNext($point[0], $point[1]); + } + + $this->bytes = $originalBytes; + } + + /** + * @return int[]|null + */ + private function findNext(int $x, int $y) : ?array + { + $i = $this->width * $y + $x; + + while ($i < $this->size && 1 !== $this->bytes[$i]) { + ++$i; + } + + if ($i < $this->size) { + return $this->pointOf($i); + } + + return null; + } + + private function findEdge(int $x, int $y) : Edge + { + $edge = new Edge($this->isSet($x, $y)); + $startX = $x; + $startY = $y; + $dirX = 0; + $dirY = 1; + + while (true) { + $edge->addPoint($x, $y); + $x += $dirX; + $y += $dirY; + + if ($x === $startX && $y === $startY) { + break; + } + + $left = $this->isSet($x + ($dirX + $dirY - 1 ) / 2, $y + ($dirY - $dirX - 1) / 2); + $right = $this->isSet($x + ($dirX - $dirY - 1) / 2, $y + ($dirY + $dirX - 1) / 2); + + if ($right && ! $left) { + $tmp = $dirX; + $dirX = -$dirY; + $dirY = $tmp; + } elseif ($right) { + $tmp = $dirX; + $dirX = -$dirY; + $dirY = $tmp; + } elseif (! $left) { + $tmp = $dirX; + $dirX = $dirY; + $dirY = -$tmp; + } + } + + return $edge; + } + + private function xorEdge(Edge $path) : void + { + $points = $path->getPoints(); + $y1 = $points[0][1]; + $length = count($points); + $maxX = $path->getMaxX(); + + for ($i = 1; $i < $length; ++$i) { + $y = $points[$i][1]; + + if ($y === $y1) { + continue; + } + + $x = $points[$i][0]; + $minY = min($y1, $y); + + for ($j = $x; $j < $maxX; ++$j) { + $this->flip($j, $minY); + } + + $y1 = $y; + } + } + + private function isSet(int $x, int $y) : bool + { + return ( + $x >= 0 + && $x < $this->width + && $y >= 0 + && $y < $this->height + ) && 1 === $this->bytes[$this->width * $y + $x]; + } + + /** + * @return int[] + */ + private function pointOf(int $i) : array + { + $y = intdiv($i, $this->width); + return [$i - $y * $this->width, $y]; + } + + private function flip(int $x, int $y) : void + { + $this->bytes[$this->width * $y + $x] = ( + $this->isSet($x, $y) ? 0 : 1 + ); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php b/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php new file mode 100644 index 0000000..0ccb0e0 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Module/ModuleInterface.php @@ -0,0 +1,18 @@ + 1) { + throw new InvalidArgumentException('Intensity must between 0 (exclusive) and 1 (inclusive)'); + } + + $this->intensity = $intensity / 2; + } + + public function createPath(ByteMatrix $matrix) : Path + { + $path = new Path(); + + foreach (new EdgeIterator($matrix) as $edge) { + $points = $edge->getSimplifiedPoints(); + $length = count($points); + + $currentPoint = $points[0]; + $nextPoint = $points[1]; + $horizontal = ($currentPoint[1] === $nextPoint[1]); + + if ($horizontal) { + $right = $nextPoint[0] > $currentPoint[0]; + $path = $path->move( + $currentPoint[0] + ($right ? $this->intensity : -$this->intensity), + $currentPoint[1] + ); + } else { + $up = $nextPoint[0] < $currentPoint[0]; + $path = $path->move( + $currentPoint[0], + $currentPoint[1] + ($up ? -$this->intensity : $this->intensity) + ); + } + + for ($i = 1; $i <= $length; ++$i) { + if ($i === $length) { + $previousPoint = $points[$length - 1]; + $currentPoint = $points[0]; + $nextPoint = $points[1]; + } else { + $previousPoint = $points[(0 === $i ? $length : $i) - 1]; + $currentPoint = $points[$i]; + $nextPoint = $points[($length - 1 === $i ? -1 : $i) + 1]; + } + + $horizontal = ($previousPoint[1] === $currentPoint[1]); + + if ($horizontal) { + $right = $previousPoint[0] < $currentPoint[0]; + $up = $nextPoint[1] < $currentPoint[1]; + $sweep = ($up xor $right); + + if ($this->intensity < 0.5 + || ($right && $previousPoint[0] !== $currentPoint[0] - 1) + || (! $right && $previousPoint[0] - 1 !== $currentPoint[0]) + ) { + $path = $path->line( + $currentPoint[0] + ($right ? -$this->intensity : $this->intensity), + $currentPoint[1] + ); + } + + $path = $path->ellipticArc( + $this->intensity, + $this->intensity, + 0, + false, + $sweep, + $currentPoint[0], + $currentPoint[1] + ($up ? -$this->intensity : $this->intensity) + ); + } else { + $up = $previousPoint[1] > $currentPoint[1]; + $right = $nextPoint[0] > $currentPoint[0]; + $sweep = ! ($up xor $right); + + if ($this->intensity < 0.5 + || ($up && $previousPoint[1] !== $currentPoint[1] + 1) + || (! $up && $previousPoint[0] + 1 !== $currentPoint[0]) + ) { + $path = $path->line( + $currentPoint[0], + $currentPoint[1] + ($up ? $this->intensity : -$this->intensity) + ); + } + + $path = $path->ellipticArc( + $this->intensity, + $this->intensity, + 0, + false, + $sweep, + $currentPoint[0] + ($right ? $this->intensity : -$this->intensity), + $currentPoint[1] + ); + } + } + + $path = $path->close(); + } + + return $path; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php b/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php new file mode 100644 index 0000000..8cf1d0b --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Module/SquareModule.php @@ -0,0 +1,44 @@ +getSimplifiedPoints(); + $length = count($points); + $path = $path->move($points[0][0], $points[0][1]); + + for ($i = 1; $i < $length; ++$i) { + $path = $path->line($points[$i][0], $points[$i][1]); + } + + $path = $path->close(); + } + + return $path; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php b/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php new file mode 100644 index 0000000..bddf2d0 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Path/Close.php @@ -0,0 +1,34 @@ +x1; + } + + public function getY1() : float + { + return $this->y1; + } + + public function getX2() : float + { + return $this->x2; + } + + public function getY2() : float + { + return $this->y2; + } + + public function getX3() : float + { + return $this->x3; + } + + public function getY3() : float + { + return $this->y3; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self( + $this->x1 + $x, + $this->y1 + $y, + $this->x2 + $x, + $this->y2 + $y, + $this->x3 + $x, + $this->y3 + $y + ); + } + + /** + * @return self + */ + public function rotate(int $degrees) : OperationInterface + { + $radians = deg2rad($degrees); + $sin = sin($radians); + $cos = cos($radians); + $x1r = $this->x1 * $cos - $this->y1 * $sin; + $y1r = $this->x1 * $sin + $this->y1 * $cos; + $x2r = $this->x2 * $cos - $this->y2 * $sin; + $y2r = $this->x2 * $sin + $this->y2 * $cos; + $x3r = $this->x3 * $cos - $this->y3 * $sin; + $y3r = $this->x3 * $sin + $this->y3 * $cos; + return new self( + $x1r, + $y1r, + $x2r, + $y2r, + $x3r, + $y3r + ); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php b/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php new file mode 100644 index 0000000..ee957d4 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Path/EllipticArc.php @@ -0,0 +1,264 @@ +xRadius = abs($xRadius); + $this->yRadius = abs($yRadius); + $this->xAxisAngle = $xAxisAngle % 360; + } + + public function getXRadius() : float + { + return $this->xRadius; + } + + public function getYRadius() : float + { + return $this->yRadius; + } + + public function getXAxisAngle() : float + { + return $this->xAxisAngle; + } + + public function isLargeArc() : bool + { + return $this->largeArc; + } + + public function isSweep() : bool + { + return $this->sweep; + } + + public function getX() : float + { + return $this->x; + } + + public function getY() : float + { + return $this->y; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self( + $this->xRadius, + $this->yRadius, + $this->xAxisAngle, + $this->largeArc, + $this->sweep, + $this->x + $x, + $this->y + $y + ); + } + + /** + * @return self + */ + public function rotate(int $degrees) : OperationInterface + { + $radians = deg2rad($degrees); + $sin = sin($radians); + $cos = cos($radians); + $xr = $this->x * $cos - $this->y * $sin; + $yr = $this->x * $sin + $this->y * $cos; + return new self( + $this->xRadius, + $this->yRadius, + $this->xAxisAngle, + $this->largeArc, + $this->sweep, + $xr, + $yr + ); + } + + /** + * Converts the elliptic arc to multiple curves. + * + * Since not all image back ends support elliptic arcs, this method allows to convert the arc into multiple curves + * resembling the same result. + * + * @see https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ + * @return array + */ + public function toCurves(float $fromX, float $fromY) : array + { + if (sqrt(($fromX - $this->x) ** 2 + ($fromY - $this->y) ** 2) < self::ZERO_TOLERANCE) { + return []; + } + + if ($this->xRadius < self::ZERO_TOLERANCE || $this->yRadius < self::ZERO_TOLERANCE) { + return [new Line($this->x, $this->y)]; + } + + return $this->createCurves($fromX, $fromY); + } + + /** + * @return Curve[] + */ + private function createCurves(float $fromX, float $fromY) : array + { + $xAngle = deg2rad($this->xAxisAngle); + list($centerX, $centerY, $radiusX, $radiusY, $startAngle, $deltaAngle) = + $this->calculateCenterPointParameters($fromX, $fromY, $xAngle); + + $s = $startAngle; + $e = $s + $deltaAngle; + $sign = ($e < $s) ? -1 : 1; + $remain = abs($e - $s); + $p1 = self::point($centerX, $centerY, $radiusX, $radiusY, $xAngle, $s); + $curves = []; + + while ($remain > self::ZERO_TOLERANCE) { + $step = min($remain, pi() / 2); + $signStep = $step * $sign; + $p2 = self::point($centerX, $centerY, $radiusX, $radiusY, $xAngle, $s + $signStep); + + $alphaT = tan($signStep / 2); + $alpha = sin($signStep) * (sqrt(4 + 3 * $alphaT ** 2) - 1) / 3; + $d1 = self::derivative($radiusX, $radiusY, $xAngle, $s); + $d2 = self::derivative($radiusX, $radiusY, $xAngle, $s + $signStep); + + $curves[] = new Curve( + $p1[0] + $alpha * $d1[0], + $p1[1] + $alpha * $d1[1], + $p2[0] - $alpha * $d2[0], + $p2[1] - $alpha * $d2[1], + $p2[0], + $p2[1] + ); + + $s += $signStep; + $remain -= $step; + $p1 = $p2; + } + + return $curves; + } + + /** + * @return float[] + */ + private function calculateCenterPointParameters(float $fromX, float $fromY, float $xAngle): array + { + $rX = $this->xRadius; + $rY = $this->yRadius; + + // F.6.5.1 + $dx2 = ($fromX - $this->x) / 2; + $dy2 = ($fromY - $this->y) / 2; + $x1p = cos($xAngle) * $dx2 + sin($xAngle) * $dy2; + $y1p = -sin($xAngle) * $dx2 + cos($xAngle) * $dy2; + + // F.6.5.2 + $rxs = $rX ** 2; + $rys = $rY ** 2; + $x1ps = $x1p ** 2; + $y1ps = $y1p ** 2; + $cr = $x1ps / $rxs + $y1ps / $rys; + + if ($cr > 1) { + $s = sqrt($cr); + $rX *= $s; + $rY *= $s; + $rxs = $rX ** 2; + $rys = $rY ** 2; + } + + $dq = ($rxs * $y1ps + $rys * $x1ps); + $pq = ($rxs * $rys - $dq) / $dq; + $q = sqrt(max(0, $pq)); + + if ($this->largeArc === $this->sweep) { + $q = -$q; + } + + $cxp = $q * $rX * $y1p / $rY; + $cyp = -$q * $rY * $x1p / $rX; + + // F.6.5.3 + $cx = cos($xAngle) * $cxp - sin($xAngle) * $cyp + ($fromX + $this->x) / 2; + $cy = sin($xAngle) * $cxp + cos($xAngle) * $cyp + ($fromY + $this->y) / 2; + + // F.6.5.5 + $theta = self::angle(1, 0, ($x1p - $cxp) / $rX, ($y1p - $cyp) / $rY); + + // F.6.5.6 + $delta = self::angle(($x1p - $cxp) / $rX, ($y1p - $cyp) / $rY, (-$x1p - $cxp) / $rX, (-$y1p - $cyp) / $rY); + $delta = fmod($delta, pi() * 2); + + if (! $this->sweep) { + $delta -= 2 * pi(); + } + + return [$cx, $cy, $rX, $rY, $theta, $delta]; + } + + private static function angle(float $ux, float $uy, float $vx, float $vy) : float + { + // F.6.5.4 + $dot = $ux * $vx + $uy * $vy; + $length = sqrt($ux ** 2 + $uy ** 2) * sqrt($vx ** 2 + $vy ** 2); + $angle = acos(min(1, max(-1, $dot / $length))); + + if (($ux * $vy - $uy * $vx) < 0) { + return -$angle; + } + + return $angle; + } + + /** + * @return float[] + */ + private static function point( + float $centerX, + float $centerY, + float $radiusX, + float $radiusY, + float $xAngle, + float $angle + ) : array { + return [ + $centerX + $radiusX * cos($xAngle) * cos($angle) - $radiusY * sin($xAngle) * sin($angle), + $centerY + $radiusX * sin($xAngle) * cos($angle) + $radiusY * cos($xAngle) * sin($angle), + ]; + } + + /** + * @return float[] + */ + private static function derivative(float $radiusX, float $radiusY, float $xAngle, float $angle) : array + { + return [ + -$radiusX * cos($xAngle) * sin($angle) - $radiusY * sin($xAngle) * cos($angle), + -$radiusX * sin($xAngle) * sin($angle) + $radiusY * cos($xAngle) * cos($angle), + ]; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php b/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php new file mode 100644 index 0000000..dec46fd --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Path/Line.php @@ -0,0 +1,42 @@ +x; + } + + public function getY() : float + { + return $this->y; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self($this->x + $x, $this->y + $y); + } + + /** + * @return self + */ + public function rotate(int $degrees) : OperationInterface + { + $radians = deg2rad($degrees); + $sin = sin($radians); + $cos = cos($radians); + $xr = $this->x * $cos - $this->y * $sin; + $yr = $this->x * $sin + $this->y * $cos; + return new self($xr, $yr); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php b/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php new file mode 100644 index 0000000..c3c9a56 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Path/Move.php @@ -0,0 +1,42 @@ +x; + } + + public function getY() : float + { + return $this->y; + } + + /** + * @return self + */ + public function translate(float $x, float $y) : OperationInterface + { + return new self($this->x + $x, $this->y + $y); + } + + /** + * @return self + */ + public function rotate(int $degrees) : OperationInterface + { + $radians = deg2rad($degrees); + $sin = sin($radians); + $cos = cos($radians); + $xr = $this->x * $cos - $this->y * $sin; + $yr = $this->x * $sin + $this->y * $cos; + return new self($xr, $yr); + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php b/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php new file mode 100644 index 0000000..9271555 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/Path/OperationInterface.php @@ -0,0 +1,17 @@ +operations[] = new Move($x, $y); + return $path; + } + + /** + * Draws a line from the current position to another position. + */ + public function line(float $x, float $y) : self + { + $path = clone $this; + $path->operations[] = new Line($x, $y); + return $path; + } + + /** + * Draws an elliptic arc from the current position to another position. + */ + public function ellipticArc( + float $xRadius, + float $yRadius, + float $xAxisRotation, + bool $largeArc, + bool $sweep, + float $x, + float $y + ) : self { + $path = clone $this; + $path->operations[] = new EllipticArc($xRadius, $yRadius, $xAxisRotation, $largeArc, $sweep, $x, $y); + return $path; + } + + /** + * Draws a curve from the current position to another position. + */ + public function curve(float $x1, float $y1, float $x2, float $y2, float $x3, float $y3) : self + { + $path = clone $this; + $path->operations[] = new Curve($x1, $y1, $x2, $y2, $x3, $y3); + return $path; + } + + /** + * Closes a sub-path. + */ + public function close() : self + { + $path = clone $this; + $path->operations[] = Close::instance(); + return $path; + } + + /** + * Appends another path to this one. + */ + public function append(self $other) : self + { + $path = clone $this; + $path->operations = array_merge($this->operations, $other->operations); + return $path; + } + + public function translate(float $x, float $y) : self + { + $path = new self(); + + foreach ($this->operations as $operation) { + $path->operations[] = $operation->translate($x, $y); + } + + return $path; + } + + public function rotate(int $degrees) : self + { + $path = new self(); + + foreach ($this->operations as $operation) { + $path->operations[] = $operation->rotate($degrees); + } + + return $path; + } + + /** + * @return Traversable + */ + public function getIterator() : Traversable + { + foreach ($this->operations as $operation) { + yield $operation; + } + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php b/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php new file mode 100644 index 0000000..219bbf3 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/PlainTextRenderer.php @@ -0,0 +1,80 @@ +getMatrix(); + $matrixSize = $matrix->getWidth(); + + if ($matrixSize !== $matrix->getHeight()) { + throw new InvalidArgumentException('Matrix must have the same width and height'); + } + + $rows = $matrix->getArray()->toArray(); + + if (0 !== $matrixSize % 2) { + $rows[] = array_fill(0, $matrixSize, 0); + } + + $horizontalMargin = str_repeat(self::EMPTY_BLOCK, $this->margin); + $result = str_repeat("\n", (int) ceil($this->margin / 2)); + + for ($i = 0; $i < $matrixSize; $i += 2) { + $result .= $horizontalMargin; + + $upperRow = $rows[$i]; + $lowerRow = $rows[$i + 1]; + + for ($j = 0; $j < $matrixSize; ++$j) { + $upperBit = $upperRow[$j]; + $lowerBit = $lowerRow[$j]; + + if ($upperBit) { + $result .= $lowerBit ? self::FULL_BLOCK : self::UPPER_HALF_BLOCK; + } else { + $result .= $lowerBit ? self::LOWER_HALF_BLOCK : self::EMPTY_BLOCK; + } + } + + $result .= $horizontalMargin . "\n"; + } + + $result .= str_repeat("\n", (int) ceil($this->margin / 2)); + + return $result; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php b/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php new file mode 100644 index 0000000..b0aae39 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/RendererInterface.php @@ -0,0 +1,11 @@ +externalColor && null === $this->internalColor; + } + + public function inheritsExternalColor() : bool + { + return null === $this->externalColor; + } + + public function inheritsInternalColor() : bool + { + return null === $this->internalColor; + } + + public function getExternalColor() : ColorInterface + { + if (null === $this->externalColor) { + throw new RuntimeException('External eye color inherits foreground color'); + } + + return $this->externalColor; + } + + public function getInternalColor() : ColorInterface + { + if (null === $this->internalColor) { + throw new RuntimeException('Internal eye color inherits foreground color'); + } + + return $this->internalColor; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php b/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php new file mode 100644 index 0000000..19de25d --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Fill.php @@ -0,0 +1,129 @@ +foregroundGradient; + } + + public function getBackgroundColor() : ColorInterface + { + return $this->backgroundColor; + } + + public function getForegroundColor() : ColorInterface + { + if (null === $this->foregroundColor) { + throw new RuntimeException('Fill uses a gradient, thus no foreground color is available'); + } + + return $this->foregroundColor; + } + + public function getForegroundGradient() : Gradient + { + if (null === $this->foregroundGradient) { + throw new RuntimeException('Fill uses a single color, thus no foreground gradient is available'); + } + + return $this->foregroundGradient; + } + + public function getTopLeftEyeFill() : EyeFill + { + return $this->topLeftEyeFill; + } + + public function getTopRightEyeFill() : EyeFill + { + return $this->topRightEyeFill; + } + + public function getBottomLeftEyeFill() : EyeFill + { + return $this->bottomLeftEyeFill; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php b/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php new file mode 100644 index 0000000..eea4031 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/Gradient.php @@ -0,0 +1,31 @@ +startColor; + } + + public function getEndColor() : ColorInterface + { + return $this->endColor; + } + + public function getType() : GradientType + { + return $this->type; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php b/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php new file mode 100644 index 0000000..c1ca754 --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Renderer/RendererStyle/GradientType.php @@ -0,0 +1,22 @@ +module = $module ?: SquareModule::instance(); + $this->eye = $eye ?: new ModuleEye($this->module); + $this->fill = $fill ?: Fill::default(); + } + + public function withSize(int $size) : self + { + $style = clone $this; + $style->size = $size; + return $style; + } + + public function withMargin(int $margin) : self + { + $style = clone $this; + $style->margin = $margin; + return $style; + } + + public function getSize() : int + { + return $this->size; + } + + public function getMargin() : int + { + return $this->margin; + } + + public function getModule() : ModuleInterface + { + return $this->module; + } + + public function getEye() : EyeInterface + { + return $this->eye; + } + + public function getFill() : Fill + { + return $this->fill; + } +} diff --git a/vendor/bacon/bacon-qr-code/src/Writer.php b/vendor/bacon/bacon-qr-code/src/Writer.php new file mode 100644 index 0000000..d7f7ebb --- /dev/null +++ b/vendor/bacon/bacon-qr-code/src/Writer.php @@ -0,0 +1,63 @@ +renderer->render(Encoder::encode($content, $ecLevel, $encoding, $forcedVersion)); + } + + /** + * Writes QR code to a file. + * + * @see Writer::writeString() + */ + public function writeFile( + string $content, + string $filename, + string $encoding = Encoder::DEFAULT_BYTE_MODE_ENCODING, + ?ErrorCorrectionLevel $ecLevel = null, + ?Version $forcedVersion = null + ) : void { + file_put_contents($filename, $this->writeString($content, $encoding, $ecLevel, $forcedVersion)); + } +} diff --git a/vendor/bin/latte-lint b/vendor/bin/latte-lint new file mode 100644 index 0000000..df90b81 --- /dev/null +++ b/vendor/bin/latte-lint @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/latte/latte/bin/latte-lint'); + } +} + +return include __DIR__ . '/..'.'/latte/latte/bin/latte-lint'; diff --git a/vendor/bin/latte-lint.bat b/vendor/bin/latte-lint.bat new file mode 100644 index 0000000..2fb8891 --- /dev/null +++ b/vendor/bin/latte-lint.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/latte-lint +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/neon-lint b/vendor/bin/neon-lint new file mode 100644 index 0000000..c774123 --- /dev/null +++ b/vendor/bin/neon-lint @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/nette/neon/bin/neon-lint'); + } +} + +return include __DIR__ . '/..'.'/nette/neon/bin/neon-lint'; diff --git a/vendor/bin/neon-lint.bat b/vendor/bin/neon-lint.bat new file mode 100644 index 0000000..31fa117 --- /dev/null +++ b/vendor/bin/neon-lint.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/neon-lint +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/phpstan b/vendor/bin/phpstan new file mode 100644 index 0000000..d76c0be --- /dev/null +++ b/vendor/bin/phpstan @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpstan/phpstan/phpstan'); + } +} + +return include __DIR__ . '/..'.'/phpstan/phpstan/phpstan'; diff --git a/vendor/bin/phpstan.bat b/vendor/bin/phpstan.bat new file mode 100644 index 0000000..7ec286d --- /dev/null +++ b/vendor/bin/phpstan.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/phpstan +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/phpstan.phar b/vendor/bin/phpstan.phar new file mode 100644 index 0000000..fecf96f --- /dev/null +++ b/vendor/bin/phpstan.phar @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/phpstan/phpstan/phpstan.phar'); + } +} + +return include __DIR__ . '/..'.'/phpstan/phpstan/phpstan.phar'; diff --git a/vendor/bin/phpstan.phar.bat b/vendor/bin/phpstan.phar.bat new file mode 100644 index 0000000..5f4d9eb --- /dev/null +++ b/vendor/bin/phpstan.phar.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/phpstan.phar +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/bin/tester b/vendor/bin/tester new file mode 100644 index 0000000..d800307 --- /dev/null +++ b/vendor/bin/tester @@ -0,0 +1,119 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + return include("phpvfscomposer://" . __DIR__ . '/..'.'/nette/tester/src/tester'); + } +} + +return include __DIR__ . '/..'.'/nette/tester/src/tester'; diff --git a/vendor/bin/tester.bat b/vendor/bin/tester.bat new file mode 100644 index 0000000..3402472 --- /dev/null +++ b/vendor/bin/tester.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/tester +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..7824d8f --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,579 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..51e734a --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} 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..5e8f1d0 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,696 @@ + $vendorDir . '/composer/InstalledVersions.php', + 'Latte\\Attributes\\TemplateFilter' => $vendorDir . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Attributes\\TemplateFunction' => $vendorDir . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Bridges\\Tracy\\BlueScreenPanel' => $vendorDir . '/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php', + 'Latte\\Bridges\\Tracy\\LattePanel' => $vendorDir . '/latte/latte/src/Bridges/Tracy/LattePanel.php', + 'Latte\\Bridges\\Tracy\\TracyExtension' => $vendorDir . '/latte/latte/src/Bridges/Tracy/TracyExtension.php', + 'Latte\\Cache' => $vendorDir . '/latte/latte/src/Latte/Cache.php', + 'Latte\\CompileException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Compiler\\Block' => $vendorDir . '/latte/latte/src/Latte/Compiler/Block.php', + 'Latte\\Compiler\\Escaper' => $vendorDir . '/latte/latte/src/Latte/Compiler/Escaper.php', + 'Latte\\Compiler\\Node' => $vendorDir . '/latte/latte/src/Latte/Compiler/Node.php', + 'Latte\\Compiler\\NodeHelpers' => $vendorDir . '/latte/latte/src/Latte/Compiler/NodeHelpers.php', + 'Latte\\Compiler\\NodeTraverser' => $vendorDir . '/latte/latte/src/Latte/Compiler/NodeTraverser.php', + 'Latte\\Compiler\\Nodes\\AreaNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php', + 'Latte\\Compiler\\Nodes\\AuxiliaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\FragmentNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\AttributeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\BogusTagNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php', + 'Latte\\Compiler\\Nodes\\Html\\CommentNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ElementNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ExpressionAttributeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\TagNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php', + 'Latte\\Compiler\\Nodes\\NopNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/NopNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArgumentNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArrayItemNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ClosureUseNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ComplexTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ExpressionNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayAccessNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AuxiliaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\BinaryOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CastNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClassConstantFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CloneNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClosureNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ConstantFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\EmptyNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FilterCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FunctionCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InstanceofNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\IssetNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MatchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\NewNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PostOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PreOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticMethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticPropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TemporaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TernaryNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\UnaryOpNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\VariableNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php', + 'Latte\\Compiler\\Nodes\\Php\\FilterNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IdentifierNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\InterpolatedStringPartNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IntersectionTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListItemNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php', + 'Latte\\Compiler\\Nodes\\Php\\MatchArmNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ModifierNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NameNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NullableTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\OperatorNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ParameterNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ScalarNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\BooleanNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\FloatNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\IntegerNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\InterpolatedStringNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\NullNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\StringNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\SuperiorTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\UnionTypeNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VarLikeIdentifierNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VariadicPlaceholderNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php', + 'Latte\\Compiler\\Nodes\\PrintNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/PrintNode.php', + 'Latte\\Compiler\\Nodes\\StatementNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php', + 'Latte\\Compiler\\Nodes\\TemplateNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php', + 'Latte\\Compiler\\Nodes\\TextNode' => $vendorDir . '/latte/latte/src/Latte/Compiler/Nodes/TextNode.php', + 'Latte\\Compiler\\PhpHelpers' => $vendorDir . '/latte/latte/src/Latte/Compiler/PhpHelpers.php', + 'Latte\\Compiler\\Position' => $vendorDir . '/latte/latte/src/Latte/Compiler/Position.php', + 'Latte\\Compiler\\PrintContext' => $vendorDir . '/latte/latte/src/Latte/Compiler/PrintContext.php', + 'Latte\\Compiler\\Tag' => $vendorDir . '/latte/latte/src/Latte/Compiler/Tag.php', + 'Latte\\Compiler\\TagLexer' => $vendorDir . '/latte/latte/src/Latte/Compiler/TagLexer.php', + 'Latte\\Compiler\\TagParser' => $vendorDir . '/latte/latte/src/Latte/Compiler/TagParser.php', + 'Latte\\Compiler\\TagParserData' => $vendorDir . '/latte/latte/src/Latte/Compiler/TagParserData.php', + 'Latte\\Compiler\\TemplateGenerator' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateGenerator.php', + 'Latte\\Compiler\\TemplateLexer' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateLexer.php', + 'Latte\\Compiler\\TemplateParser' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateParser.php', + 'Latte\\Compiler\\TemplateParserHtml' => $vendorDir . '/latte/latte/src/Latte/Compiler/TemplateParserHtml.php', + 'Latte\\Compiler\\Token' => $vendorDir . '/latte/latte/src/Latte/Compiler/Token.php', + 'Latte\\Compiler\\TokenStream' => $vendorDir . '/latte/latte/src/Latte/Compiler/TokenStream.php', + 'Latte\\ContentType' => $vendorDir . '/latte/latte/src/Latte/ContentType.php', + 'Latte\\Engine' => $vendorDir . '/latte/latte/src/Latte/Engine.php', + 'Latte\\Essential\\AuxiliaryIterator' => $vendorDir . '/latte/latte/src/Latte/Essential/AuxiliaryIterator.php', + 'Latte\\Essential\\Blueprint' => $vendorDir . '/latte/latte/src/Latte/Essential/Blueprint.php', + 'Latte\\Essential\\CachingIterator' => $vendorDir . '/latte/latte/src/Latte/Essential/CachingIterator.php', + 'Latte\\Essential\\CoreExtension' => $vendorDir . '/latte/latte/src/Latte/Essential/CoreExtension.php', + 'Latte\\Essential\\Filters' => $vendorDir . '/latte/latte/src/Latte/Essential/Filters.php', + 'Latte\\Essential\\Nodes\\BlockNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/BlockNode.php', + 'Latte\\Essential\\Nodes\\CaptureNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php', + 'Latte\\Essential\\Nodes\\ContentTypeNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php', + 'Latte\\Essential\\Nodes\\CustomFunctionCallNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php', + 'Latte\\Essential\\Nodes\\DebugbreakNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php', + 'Latte\\Essential\\Nodes\\DefineNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DefineNode.php', + 'Latte\\Essential\\Nodes\\DoNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DoNode.php', + 'Latte\\Essential\\Nodes\\DumpNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/DumpNode.php', + 'Latte\\Essential\\Nodes\\EmbedNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php', + 'Latte\\Essential\\Nodes\\ExtendsNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php', + 'Latte\\Essential\\Nodes\\FirstLastSepNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php', + 'Latte\\Essential\\Nodes\\ForNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ForNode.php', + 'Latte\\Essential\\Nodes\\ForeachNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php', + 'Latte\\Essential\\Nodes\\IfChangedNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php', + 'Latte\\Essential\\Nodes\\IfContentNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php', + 'Latte\\Essential\\Nodes\\IfNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IfNode.php', + 'Latte\\Essential\\Nodes\\ImportNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ImportNode.php', + 'Latte\\Essential\\Nodes\\IncludeBlockNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php', + 'Latte\\Essential\\Nodes\\IncludeFileNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php', + 'Latte\\Essential\\Nodes\\IterateWhileNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php', + 'Latte\\Essential\\Nodes\\JumpNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/JumpNode.php', + 'Latte\\Essential\\Nodes\\NAttrNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php', + 'Latte\\Essential\\Nodes\\NClassNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NClassNode.php', + 'Latte\\Essential\\Nodes\\NElseNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NElseNode.php', + 'Latte\\Essential\\Nodes\\NTagNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/NTagNode.php', + 'Latte\\Essential\\Nodes\\ParametersNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php', + 'Latte\\Essential\\Nodes\\RawPhpNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php', + 'Latte\\Essential\\Nodes\\RollbackNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php', + 'Latte\\Essential\\Nodes\\SpacelessNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php', + 'Latte\\Essential\\Nodes\\SwitchNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php', + 'Latte\\Essential\\Nodes\\TemplatePrintNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php', + 'Latte\\Essential\\Nodes\\TemplateTypeNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php', + 'Latte\\Essential\\Nodes\\TraceNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TraceNode.php', + 'Latte\\Essential\\Nodes\\TranslateNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php', + 'Latte\\Essential\\Nodes\\TryNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/TryNode.php', + 'Latte\\Essential\\Nodes\\VarNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/VarNode.php', + 'Latte\\Essential\\Nodes\\VarPrintNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php', + 'Latte\\Essential\\Nodes\\VarTypeNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php', + 'Latte\\Essential\\Nodes\\WhileNode' => $vendorDir . '/latte/latte/src/Latte/Essential/Nodes/WhileNode.php', + 'Latte\\Essential\\Passes' => $vendorDir . '/latte/latte/src/Latte/Essential/Passes.php', + 'Latte\\Essential\\RawPhpExtension' => $vendorDir . '/latte/latte/src/Latte/Essential/RawPhpExtension.php', + 'Latte\\Essential\\RollbackException' => $vendorDir . '/latte/latte/src/Latte/Essential/RollbackException.php', + 'Latte\\Essential\\Tracer' => $vendorDir . '/latte/latte/src/Latte/Essential/Tracer.php', + 'Latte\\Essential\\TranslatorExtension' => $vendorDir . '/latte/latte/src/Latte/Essential/TranslatorExtension.php', + 'Latte\\Exception' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Extension' => $vendorDir . '/latte/latte/src/Latte/Extension.php', + 'Latte\\Helpers' => $vendorDir . '/latte/latte/src/Latte/Helpers.php', + 'Latte\\Loader' => $vendorDir . '/latte/latte/src/Latte/Loader.php', + 'Latte\\Loaders\\FileLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/FileLoader.php', + 'Latte\\Loaders\\StringLoader' => $vendorDir . '/latte/latte/src/Latte/Loaders/StringLoader.php', + 'Latte\\Policy' => $vendorDir . '/latte/latte/src/Latte/Policy.php', + 'Latte\\PositionAwareException' => $vendorDir . '/latte/latte/src/Latte/PositionAwareException.php', + 'Latte\\RuntimeException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Runtime\\Block' => $vendorDir . '/latte/latte/src/Latte/Runtime/Block.php', + 'Latte\\Runtime\\FilterExecutor' => $vendorDir . '/latte/latte/src/Latte/Runtime/FilterExecutor.php', + 'Latte\\Runtime\\FilterInfo' => $vendorDir . '/latte/latte/src/Latte/Runtime/FilterInfo.php', + 'Latte\\Runtime\\FunctionExecutor' => $vendorDir . '/latte/latte/src/Latte/Runtime/FunctionExecutor.php', + 'Latte\\Runtime\\Helpers' => $vendorDir . '/latte/latte/src/Latte/Runtime/Helpers.php', + 'Latte\\Runtime\\Html' => $vendorDir . '/latte/latte/src/Latte/Runtime/Html.php', + 'Latte\\Runtime\\HtmlHelpers' => $vendorDir . '/latte/latte/src/Latte/Runtime/HtmlHelpers.php', + 'Latte\\Runtime\\HtmlStringable' => $vendorDir . '/latte/latte/src/Latte/Runtime/HtmlStringable.php', + 'Latte\\Runtime\\Template' => $vendorDir . '/latte/latte/src/Latte/Runtime/Template.php', + 'Latte\\Runtime\\XmlHelpers' => $vendorDir . '/latte/latte/src/Latte/Runtime/XmlHelpers.php', + 'Latte\\Sandbox\\Nodes\\FunctionCallNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php', + 'Latte\\Sandbox\\Nodes\\MethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\PropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php', + 'Latte\\Sandbox\\Nodes\\SandboxNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php', + 'Latte\\Sandbox\\Nodes\\StaticMethodCallNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\StaticPropertyFetchNode' => $vendorDir . '/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php', + 'Latte\\Sandbox\\RuntimeChecker' => $vendorDir . '/latte/latte/src/Latte/Sandbox/RuntimeChecker.php', + 'Latte\\Sandbox\\SandboxExtension' => $vendorDir . '/latte/latte/src/Latte/Sandbox/SandboxExtension.php', + 'Latte\\Sandbox\\SecurityPolicy' => $vendorDir . '/latte/latte/src/Latte/Sandbox/SecurityPolicy.php', + 'Latte\\SecurityViolationException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\TemplateNotFoundException' => $vendorDir . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Tools\\Linter' => $vendorDir . '/latte/latte/src/Tools/Linter.php', + 'Latte\\Tools\\LinterExtension' => $vendorDir . '/latte/latte/src/Tools/LinterExtension.php', + 'NetteModule\\ErrorPresenter' => $vendorDir . '/nette/application/src/Application/ErrorPresenter.php', + 'NetteModule\\MicroPresenter' => $vendorDir . '/nette/application/src/Application/MicroPresenter.php', + 'Nette\\Application\\AbortException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Application' => $vendorDir . '/nette/application/src/Application/Application.php', + 'Nette\\Application\\ApplicationException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Attributes\\CrossOrigin' => $vendorDir . '/nette/application/src/Application/Attributes/CrossOrigin.php', + 'Nette\\Application\\Attributes\\Deprecated' => $vendorDir . '/nette/application/src/Application/Attributes/Deprecated.php', + 'Nette\\Application\\Attributes\\Parameter' => $vendorDir . '/nette/application/src/Application/Attributes/Parameter.php', + 'Nette\\Application\\Attributes\\Persistent' => $vendorDir . '/nette/application/src/Application/Attributes/Persistent.php', + 'Nette\\Application\\Attributes\\Requires' => $vendorDir . '/nette/application/src/Application/Attributes/Requires.php', + 'Nette\\Application\\Attributes\\TemplateVariable' => $vendorDir . '/nette/application/src/Application/Attributes/TemplateVariable.php', + 'Nette\\Application\\BadRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\ForbiddenRequestException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Helpers' => $vendorDir . '/nette/application/src/Application/Helpers.php', + 'Nette\\Application\\IPresenter' => $vendorDir . '/nette/application/src/Application/IPresenter.php', + 'Nette\\Application\\IPresenterFactory' => $vendorDir . '/nette/application/src/Application/IPresenterFactory.php', + 'Nette\\Application\\IResponse' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\IRouter' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\InvalidPresenterException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\LinkGenerator' => $vendorDir . '/nette/application/src/Application/LinkGenerator.php', + 'Nette\\Application\\PresenterFactory' => $vendorDir . '/nette/application/src/Application/PresenterFactory.php', + 'Nette\\Application\\Request' => $vendorDir . '/nette/application/src/Application/Request.php', + 'Nette\\Application\\Response' => $vendorDir . '/nette/application/src/Application/Response.php', + 'Nette\\Application\\Responses\\CallbackResponse' => $vendorDir . '/nette/application/src/Application/Responses/CallbackResponse.php', + 'Nette\\Application\\Responses\\FileResponse' => $vendorDir . '/nette/application/src/Application/Responses/FileResponse.php', + 'Nette\\Application\\Responses\\ForwardResponse' => $vendorDir . '/nette/application/src/Application/Responses/ForwardResponse.php', + 'Nette\\Application\\Responses\\JsonResponse' => $vendorDir . '/nette/application/src/Application/Responses/JsonResponse.php', + 'Nette\\Application\\Responses\\RedirectResponse' => $vendorDir . '/nette/application/src/Application/Responses/RedirectResponse.php', + 'Nette\\Application\\Responses\\TextResponse' => $vendorDir . '/nette/application/src/Application/Responses/TextResponse.php', + 'Nette\\Application\\Responses\\VoidResponse' => $vendorDir . '/nette/application/src/Application/Responses/VoidResponse.php', + 'Nette\\Application\\Routers\\CliRouter' => $vendorDir . '/nette/application/src/Application/Routers/CliRouter.php', + 'Nette\\Application\\Routers\\Route' => $vendorDir . '/nette/application/src/Application/Routers/Route.php', + 'Nette\\Application\\Routers\\RouteList' => $vendorDir . '/nette/application/src/Application/Routers/RouteList.php', + 'Nette\\Application\\Routers\\SimpleRouter' => $vendorDir . '/nette/application/src/Application/Routers/SimpleRouter.php', + 'Nette\\Application\\SwitchException' => $vendorDir . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\UI\\AccessPolicy' => $vendorDir . '/nette/application/src/Application/UI/AccessPolicy.php', + 'Nette\\Application\\UI\\BadSignalException' => $vendorDir . '/nette/application/src/Application/UI/BadSignalException.php', + 'Nette\\Application\\UI\\Component' => $vendorDir . '/nette/application/src/Application/UI/Component.php', + 'Nette\\Application\\UI\\ComponentReflection' => $vendorDir . '/nette/application/src/Application/UI/ComponentReflection.php', + 'Nette\\Application\\UI\\Control' => $vendorDir . '/nette/application/src/Application/UI/Control.php', + 'Nette\\Application\\UI\\Form' => $vendorDir . '/nette/application/src/Application/UI/Form.php', + 'Nette\\Application\\UI\\IRenderable' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ISignalReceiver' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\IStatePersistent' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplate' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplateFactory' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\InvalidLinkException' => $vendorDir . '/nette/application/src/Application/UI/InvalidLinkException.php', + 'Nette\\Application\\UI\\Link' => $vendorDir . '/nette/application/src/Application/UI/Link.php', + 'Nette\\Application\\UI\\MethodReflection' => $vendorDir . '/nette/application/src/Application/UI/MethodReflection.php', + 'Nette\\Application\\UI\\Multiplier' => $vendorDir . '/nette/application/src/Application/UI/Multiplier.php', + 'Nette\\Application\\UI\\ParameterConverter' => $vendorDir . '/nette/application/src/Application/UI/ParameterConverter.php', + 'Nette\\Application\\UI\\Presenter' => $vendorDir . '/nette/application/src/Application/UI/Presenter.php', + 'Nette\\Application\\UI\\PresenterComponent' => $vendorDir . '/nette/application/src/compatibility.php', + 'Nette\\Application\\UI\\PresenterComponentReflection' => $vendorDir . '/nette/application/src/compatibility.php', + 'Nette\\Application\\UI\\Renderable' => $vendorDir . '/nette/application/src/Application/UI/Renderable.php', + 'Nette\\Application\\UI\\SignalReceiver' => $vendorDir . '/nette/application/src/Application/UI/SignalReceiver.php', + 'Nette\\Application\\UI\\StatePersistent' => $vendorDir . '/nette/application/src/Application/UI/StatePersistent.php', + 'Nette\\Application\\UI\\Template' => $vendorDir . '/nette/application/src/Application/UI/Template.php', + 'Nette\\Application\\UI\\TemplateFactory' => $vendorDir . '/nette/application/src/Application/UI/TemplateFactory.php', + 'Nette\\ArgumentOutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Assets\\Asset' => $vendorDir . '/nette/assets/src/Assets/Asset.php', + 'Nette\\Assets\\AssetNotFoundException' => $vendorDir . '/nette/assets/src/Assets/exceptions.php', + 'Nette\\Assets\\AudioAsset' => $vendorDir . '/nette/assets/src/Assets/AudioAsset.php', + 'Nette\\Assets\\EntryAsset' => $vendorDir . '/nette/assets/src/Assets/EntryAsset.php', + 'Nette\\Assets\\FilesystemMapper' => $vendorDir . '/nette/assets/src/Assets/FilesystemMapper.php', + 'Nette\\Assets\\FontAsset' => $vendorDir . '/nette/assets/src/Assets/FontAsset.php', + 'Nette\\Assets\\GenericAsset' => $vendorDir . '/nette/assets/src/Assets/GenericAsset.php', + 'Nette\\Assets\\Helpers' => $vendorDir . '/nette/assets/src/Assets/Helpers.php', + 'Nette\\Assets\\HtmlRenderable' => $vendorDir . '/nette/assets/src/Assets/HtmlRenderable.php', + 'Nette\\Assets\\ImageAsset' => $vendorDir . '/nette/assets/src/Assets/ImageAsset.php', + 'Nette\\Assets\\LazyLoad' => $vendorDir . '/nette/assets/src/Assets/LazyLoad.php', + 'Nette\\Assets\\Mapper' => $vendorDir . '/nette/assets/src/Assets/Mapper.php', + 'Nette\\Assets\\Registry' => $vendorDir . '/nette/assets/src/Assets/Registry.php', + 'Nette\\Assets\\ScriptAsset' => $vendorDir . '/nette/assets/src/Assets/ScriptAsset.php', + 'Nette\\Assets\\StyleAsset' => $vendorDir . '/nette/assets/src/Assets/StyleAsset.php', + 'Nette\\Assets\\VideoAsset' => $vendorDir . '/nette/assets/src/Assets/VideoAsset.php', + 'Nette\\Assets\\ViteMapper' => $vendorDir . '/nette/assets/src/Assets/ViteMapper.php', + 'Nette\\Bootstrap\\Configurator' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\Bootstrap\\Extensions\\ConstantsExtension' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Extensions/ConstantsExtension.php', + 'Nette\\Bootstrap\\Extensions\\PhpExtension' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Extensions/PhpExtension.php', + 'Nette\\Bridges\\ApplicationDI\\ApplicationExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php', + 'Nette\\Bridges\\ApplicationDI\\LatteExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/LatteExtension.php', + 'Nette\\Bridges\\ApplicationDI\\PresenterFactoryCallback' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php', + 'Nette\\Bridges\\ApplicationDI\\RoutingExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\DefaultTemplate' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php', + 'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => $vendorDir . '/nette/application/src/compatibility-intf.php', + 'Nette\\Bridges\\ApplicationLatte\\LatteFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\ControlNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/ControlNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\IfCurrentNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkBaseNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\NNonceNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetAreaNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\TemplatePrintNode' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetBridge' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetRuntime' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php', + 'Nette\\Bridges\\ApplicationLatte\\Template' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/Template.php', + 'Nette\\Bridges\\ApplicationLatte\\TemplateFactory' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\UIExtension' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\UIMacros' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIMacros.php', + 'Nette\\Bridges\\ApplicationLatte\\UIRuntime' => $vendorDir . '/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php', + 'Nette\\Bridges\\ApplicationTracy\\RoutingPanel' => $vendorDir . '/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php', + 'Nette\\Bridges\\AssetsDI\\DIExtension' => $vendorDir . '/nette/assets/src/Bridges/AssetsDI/DIExtension.php', + 'Nette\\Bridges\\AssetsLatte\\LatteExtension' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\AssetNode' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\NAssetNode' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Runtime' => $vendorDir . '/nette/assets/src/Bridges/AssetsLatte/Runtime.php', + 'Nette\\Bridges\\CacheDI\\CacheExtension' => $vendorDir . '/nette/caching/src/Bridges/CacheDI/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\CacheExtension' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\Nodes\\CacheNode' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/Nodes/CacheNode.php', + 'Nette\\Bridges\\CacheLatte\\Runtime' => $vendorDir . '/nette/caching/src/Bridges/CacheLatte/Runtime.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => $vendorDir . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\DatabaseDI\\DatabaseExtension' => $vendorDir . '/nette/database/src/Bridges/DatabaseDI/DatabaseExtension.php', + 'Nette\\Bridges\\DatabaseTracy\\ConnectionPanel' => $vendorDir . '/nette/database/src/Bridges/DatabaseTracy/ConnectionPanel.php', + 'Nette\\Bridges\\FormsDI\\FormsExtension' => $vendorDir . '/nette/forms/src/Bridges/FormsDI/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\FormMacros' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/FormMacros.php', + 'Nette\\Bridges\\FormsLatte\\FormsExtension' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FieldNNameNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormContainerNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormContainerNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNNameNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormPrintNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormPrintNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputErrorNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputErrorNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\LabelNode' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Nodes/LabelNode.php', + 'Nette\\Bridges\\FormsLatte\\Runtime' => $vendorDir . '/nette/forms/src/Bridges/FormsLatte/Runtime.php', + 'Nette\\Bridges\\HttpDI\\HttpExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/HttpExtension.php', + 'Nette\\Bridges\\HttpDI\\SessionExtension' => $vendorDir . '/nette/http/src/Bridges/HttpDI/SessionExtension.php', + 'Nette\\Bridges\\HttpTracy\\SessionPanel' => $vendorDir . '/nette/http/src/Bridges/HttpTracy/SessionPanel.php', + 'Nette\\Bridges\\MailDI\\MailExtension' => $vendorDir . '/nette/mail/src/Bridges/MailDI/MailExtension.php', + 'Nette\\Bridges\\Psr\\PsrCacheAdapter' => $vendorDir . '/nette/caching/src/Bridges/Psr/PsrCacheAdapter.php', + 'Nette\\Bridges\\SecurityDI\\SecurityExtension' => $vendorDir . '/nette/security/src/Bridges/SecurityDI/SecurityExtension.php', + 'Nette\\Bridges\\SecurityHttp\\CookieStorage' => $vendorDir . '/nette/security/src/Bridges/SecurityHttp/CookieStorage.php', + 'Nette\\Bridges\\SecurityHttp\\SessionStorage' => $vendorDir . '/nette/security/src/Bridges/SecurityHttp/SessionStorage.php', + 'Nette\\Bridges\\SecurityTracy\\UserPanel' => $vendorDir . '/nette/security/src/Bridges/SecurityTracy/UserPanel.php', + 'Nette\\Caching\\BulkReader' => $vendorDir . '/nette/caching/src/Caching/BulkReader.php', + 'Nette\\Caching\\BulkWriter' => $vendorDir . '/nette/caching/src/Caching/BulkWriter.php', + 'Nette\\Caching\\Cache' => $vendorDir . '/nette/caching/src/Caching/Cache.php', + 'Nette\\Caching\\IBulkReader' => $vendorDir . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\IStorage' => $vendorDir . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\OutputHelper' => $vendorDir . '/nette/caching/src/Caching/OutputHelper.php', + 'Nette\\Caching\\Storage' => $vendorDir . '/nette/caching/src/Caching/Storage.php', + 'Nette\\Caching\\Storages\\DevNullStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/DevNullStorage.php', + 'Nette\\Caching\\Storages\\FileStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/FileStorage.php', + 'Nette\\Caching\\Storages\\IJournal' => $vendorDir . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\Storages\\Journal' => $vendorDir . '/nette/caching/src/Caching/Storages/Journal.php', + 'Nette\\Caching\\Storages\\MemcachedStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemcachedStorage.php', + 'Nette\\Caching\\Storages\\MemoryStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/MemoryStorage.php', + 'Nette\\Caching\\Storages\\SQLiteJournal' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteJournal.php', + 'Nette\\Caching\\Storages\\SQLiteStorage' => $vendorDir . '/nette/caching/src/Caching/Storages/SQLiteStorage.php', + 'Nette\\ComponentModel\\ArrayAccess' => $vendorDir . '/nette/component-model/src/ComponentModel/ArrayAccess.php', + 'Nette\\ComponentModel\\Component' => $vendorDir . '/nette/component-model/src/ComponentModel/Component.php', + 'Nette\\ComponentModel\\Container' => $vendorDir . '/nette/component-model/src/ComponentModel/Container.php', + 'Nette\\ComponentModel\\IComponent' => $vendorDir . '/nette/component-model/src/ComponentModel/IComponent.php', + 'Nette\\ComponentModel\\IContainer' => $vendorDir . '/nette/component-model/src/ComponentModel/IContainer.php', + 'Nette\\ComponentModel\\RecursiveComponentIterator' => $vendorDir . '/nette/component-model/src/ComponentModel/RecursiveComponentIterator.php', + 'Nette\\Configurator' => $vendorDir . '/nette/bootstrap/src/Configurator.php', + 'Nette\\DI\\Attributes\\Inject' => $vendorDir . '/nette/di/src/DI/Attributes/Inject.php', + 'Nette\\DI\\Autowiring' => $vendorDir . '/nette/di/src/DI/Autowiring.php', + 'Nette\\DI\\Compiler' => $vendorDir . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => $vendorDir . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapter' => $vendorDir . '/nette/di/src/DI/Config/Adapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => $vendorDir . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => $vendorDir . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Config\\Loader' => $vendorDir . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => $vendorDir . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => $vendorDir . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => $vendorDir . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\Definitions\\AccessorDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/AccessorDefinition.php', + 'Nette\\DI\\Definitions\\Definition' => $vendorDir . '/nette/di/src/DI/Definitions/Definition.php', + 'Nette\\DI\\Definitions\\FactoryDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/FactoryDefinition.php', + 'Nette\\DI\\Definitions\\ImportedDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/ImportedDefinition.php', + 'Nette\\DI\\Definitions\\LocatorDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/LocatorDefinition.php', + 'Nette\\DI\\Definitions\\Reference' => $vendorDir . '/nette/di/src/DI/Definitions/Reference.php', + 'Nette\\DI\\Definitions\\ServiceDefinition' => $vendorDir . '/nette/di/src/DI/Definitions/ServiceDefinition.php', + 'Nette\\DI\\Definitions\\Statement' => $vendorDir . '/nette/di/src/DI/Definitions/Statement.php', + 'Nette\\DI\\DependencyChecker' => $vendorDir . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\DynamicParameter' => $vendorDir . '/nette/di/src/DI/DynamicParameter.php', + 'Nette\\DI\\Extensions\\DIExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\DefinitionSchema' => $vendorDir . '/nette/di/src/DI/Extensions/DefinitionSchema.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => $vendorDir . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\ParametersExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ParametersExtension.php', + 'Nette\\DI\\Extensions\\SearchExtension' => $vendorDir . '/nette/di/src/DI/Extensions/SearchExtension.php', + 'Nette\\DI\\Extensions\\ServicesExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ServicesExtension.php', + 'Nette\\DI\\Helpers' => $vendorDir . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\InvalidConfigurationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\MissingServiceException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\NotAllowedDuringResolvingException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => $vendorDir . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\Resolver' => $vendorDir . '/nette/di/src/DI/Resolver.php', + 'Nette\\DI\\ServiceCreationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => $vendorDir . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Statement' => $vendorDir . '/nette/di/src/compatibility.php', + 'Nette\\Database\\Connection' => $vendorDir . '/nette/database/src/Database/Connection.php', + 'Nette\\Database\\ConnectionException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\ConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Context' => $vendorDir . '/nette/database/src/compatibility.php', + 'Nette\\Database\\Conventions' => $vendorDir . '/nette/database/src/Database/Conventions.php', + 'Nette\\Database\\Conventions\\AmbiguousReferenceKeyException' => $vendorDir . '/nette/database/src/Database/Conventions/AmbiguousReferenceKeyException.php', + 'Nette\\Database\\Conventions\\DiscoveredConventions' => $vendorDir . '/nette/database/src/Database/Conventions/DiscoveredConventions.php', + 'Nette\\Database\\Conventions\\StaticConventions' => $vendorDir . '/nette/database/src/Database/Conventions/StaticConventions.php', + 'Nette\\Database\\DateTime' => $vendorDir . '/nette/database/src/Database/DateTime.php', + 'Nette\\Database\\Driver' => $vendorDir . '/nette/database/src/Database/Driver.php', + 'Nette\\Database\\DriverException' => $vendorDir . '/nette/database/src/Database/DriverException.php', + 'Nette\\Database\\Drivers\\MsSqlDriver' => $vendorDir . '/nette/database/src/Database/Drivers/MsSqlDriver.php', + 'Nette\\Database\\Drivers\\MySqlDriver' => $vendorDir . '/nette/database/src/Database/Drivers/MySqlDriver.php', + 'Nette\\Database\\Drivers\\OciDriver' => $vendorDir . '/nette/database/src/Database/Drivers/OciDriver.php', + 'Nette\\Database\\Drivers\\OdbcDriver' => $vendorDir . '/nette/database/src/Database/Drivers/OdbcDriver.php', + 'Nette\\Database\\Drivers\\PgSqlDriver' => $vendorDir . '/nette/database/src/Database/Drivers/PgSqlDriver.php', + 'Nette\\Database\\Drivers\\SqliteDriver' => $vendorDir . '/nette/database/src/Database/Drivers/SqliteDriver.php', + 'Nette\\Database\\Drivers\\SqlsrvDriver' => $vendorDir . '/nette/database/src/Database/Drivers/SqlsrvDriver.php', + 'Nette\\Database\\Explorer' => $vendorDir . '/nette/database/src/Database/Explorer.php', + 'Nette\\Database\\ForeignKeyConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Helpers' => $vendorDir . '/nette/database/src/Database/Helpers.php', + 'Nette\\Database\\IConventions' => $vendorDir . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\IRow' => $vendorDir . '/nette/database/src/Database/IRow.php', + 'Nette\\Database\\IRowContainer' => $vendorDir . '/nette/database/src/Database/IRowContainer.php', + 'Nette\\Database\\IStructure' => $vendorDir . '/nette/database/src/Database/IStructure.php', + 'Nette\\Database\\ISupplementalDriver' => $vendorDir . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\NotNullConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Reflection' => $vendorDir . '/nette/database/src/Database/Reflection.php', + 'Nette\\Database\\Reflection\\Column' => $vendorDir . '/nette/database/src/Database/Reflection/Column.php', + 'Nette\\Database\\Reflection\\ForeignKey' => $vendorDir . '/nette/database/src/Database/Reflection/ForeignKey.php', + 'Nette\\Database\\Reflection\\Index' => $vendorDir . '/nette/database/src/Database/Reflection/Index.php', + 'Nette\\Database\\Reflection\\Table' => $vendorDir . '/nette/database/src/Database/Reflection/Table.php', + 'Nette\\Database\\ResultSet' => $vendorDir . '/nette/database/src/Database/ResultSet.php', + 'Nette\\Database\\Row' => $vendorDir . '/nette/database/src/Database/Row.php', + 'Nette\\Database\\SqlLiteral' => $vendorDir . '/nette/database/src/Database/SqlLiteral.php', + 'Nette\\Database\\SqlPreprocessor' => $vendorDir . '/nette/database/src/Database/SqlPreprocessor.php', + 'Nette\\Database\\Structure' => $vendorDir . '/nette/database/src/Database/Structure.php', + 'Nette\\Database\\Table\\ActiveRow' => $vendorDir . '/nette/database/src/Database/Table/ActiveRow.php', + 'Nette\\Database\\Table\\GroupedSelection' => $vendorDir . '/nette/database/src/Database/Table/GroupedSelection.php', + 'Nette\\Database\\Table\\IRow' => $vendorDir . '/nette/database/src/Database/Table/IRow.php', + 'Nette\\Database\\Table\\IRowContainer' => $vendorDir . '/nette/database/src/Database/Table/IRowContainer.php', + 'Nette\\Database\\Table\\Selection' => $vendorDir . '/nette/database/src/Database/Table/Selection.php', + 'Nette\\Database\\Table\\SqlBuilder' => $vendorDir . '/nette/database/src/Database/Table/SqlBuilder.php', + 'Nette\\Database\\UniqueConstraintViolationException' => $vendorDir . '/nette/database/src/Database/exceptions.php', + 'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Forms\\Blueprint' => $vendorDir . '/nette/forms/src/Forms/Blueprint.php', + 'Nette\\Forms\\Container' => $vendorDir . '/nette/forms/src/Forms/Container.php', + 'Nette\\Forms\\Control' => $vendorDir . '/nette/forms/src/Forms/Control.php', + 'Nette\\Forms\\ControlGroup' => $vendorDir . '/nette/forms/src/Forms/ControlGroup.php', + 'Nette\\Forms\\Controls\\BaseControl' => $vendorDir . '/nette/forms/src/Forms/Controls/BaseControl.php', + 'Nette\\Forms\\Controls\\Button' => $vendorDir . '/nette/forms/src/Forms/Controls/Button.php', + 'Nette\\Forms\\Controls\\Checkbox' => $vendorDir . '/nette/forms/src/Forms/Controls/Checkbox.php', + 'Nette\\Forms\\Controls\\CheckboxList' => $vendorDir . '/nette/forms/src/Forms/Controls/CheckboxList.php', + 'Nette\\Forms\\Controls\\ChoiceControl' => $vendorDir . '/nette/forms/src/Forms/Controls/ChoiceControl.php', + 'Nette\\Forms\\Controls\\ColorPicker' => $vendorDir . '/nette/forms/src/Forms/Controls/ColorPicker.php', + 'Nette\\Forms\\Controls\\CsrfProtection' => $vendorDir . '/nette/forms/src/Forms/Controls/CsrfProtection.php', + 'Nette\\Forms\\Controls\\DateTimeControl' => $vendorDir . '/nette/forms/src/Forms/Controls/DateTimeControl.php', + 'Nette\\Forms\\Controls\\HiddenField' => $vendorDir . '/nette/forms/src/Forms/Controls/HiddenField.php', + 'Nette\\Forms\\Controls\\ImageButton' => $vendorDir . '/nette/forms/src/Forms/Controls/ImageButton.php', + 'Nette\\Forms\\Controls\\MultiChoiceControl' => $vendorDir . '/nette/forms/src/Forms/Controls/MultiChoiceControl.php', + 'Nette\\Forms\\Controls\\MultiSelectBox' => $vendorDir . '/nette/forms/src/Forms/Controls/MultiSelectBox.php', + 'Nette\\Forms\\Controls\\RadioList' => $vendorDir . '/nette/forms/src/Forms/Controls/RadioList.php', + 'Nette\\Forms\\Controls\\SelectBox' => $vendorDir . '/nette/forms/src/Forms/Controls/SelectBox.php', + 'Nette\\Forms\\Controls\\SubmitButton' => $vendorDir . '/nette/forms/src/Forms/Controls/SubmitButton.php', + 'Nette\\Forms\\Controls\\TextArea' => $vendorDir . '/nette/forms/src/Forms/Controls/TextArea.php', + 'Nette\\Forms\\Controls\\TextBase' => $vendorDir . '/nette/forms/src/Forms/Controls/TextBase.php', + 'Nette\\Forms\\Controls\\TextInput' => $vendorDir . '/nette/forms/src/Forms/Controls/TextInput.php', + 'Nette\\Forms\\Controls\\UploadControl' => $vendorDir . '/nette/forms/src/Forms/Controls/UploadControl.php', + 'Nette\\Forms\\Form' => $vendorDir . '/nette/forms/src/Forms/Form.php', + 'Nette\\Forms\\FormRenderer' => $vendorDir . '/nette/forms/src/Forms/FormRenderer.php', + 'Nette\\Forms\\Helpers' => $vendorDir . '/nette/forms/src/Forms/Helpers.php', + 'Nette\\Forms\\IControl' => $vendorDir . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\IFormRenderer' => $vendorDir . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\ISubmitterControl' => $vendorDir . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\Rendering\\DataClassGenerator' => $vendorDir . '/nette/forms/src/Forms/Rendering/DataClassGenerator.php', + 'Nette\\Forms\\Rendering\\DefaultFormRenderer' => $vendorDir . '/nette/forms/src/Forms/Rendering/DefaultFormRenderer.php', + 'Nette\\Forms\\Rendering\\LatteRenderer' => $vendorDir . '/nette/forms/src/Forms/Rendering/LatteRenderer.php', + 'Nette\\Forms\\Rule' => $vendorDir . '/nette/forms/src/Forms/Rule.php', + 'Nette\\Forms\\Rules' => $vendorDir . '/nette/forms/src/Forms/Rules.php', + 'Nette\\Forms\\SubmitterControl' => $vendorDir . '/nette/forms/src/Forms/SubmitterControl.php', + 'Nette\\Forms\\Validator' => $vendorDir . '/nette/forms/src/Forms/Validator.php', + 'Nette\\HtmlStringable' => $vendorDir . '/nette/utils/src/HtmlStringable.php', + 'Nette\\Http\\Context' => $vendorDir . '/nette/http/src/Http/Context.php', + 'Nette\\Http\\FileUpload' => $vendorDir . '/nette/http/src/Http/FileUpload.php', + 'Nette\\Http\\Helpers' => $vendorDir . '/nette/http/src/Http/Helpers.php', + 'Nette\\Http\\IRequest' => $vendorDir . '/nette/http/src/Http/IRequest.php', + 'Nette\\Http\\IResponse' => $vendorDir . '/nette/http/src/Http/IResponse.php', + 'Nette\\Http\\Request' => $vendorDir . '/nette/http/src/Http/Request.php', + 'Nette\\Http\\RequestFactory' => $vendorDir . '/nette/http/src/Http/RequestFactory.php', + 'Nette\\Http\\Response' => $vendorDir . '/nette/http/src/Http/Response.php', + 'Nette\\Http\\Session' => $vendorDir . '/nette/http/src/Http/Session.php', + 'Nette\\Http\\SessionSection' => $vendorDir . '/nette/http/src/Http/SessionSection.php', + 'Nette\\Http\\Url' => $vendorDir . '/nette/http/src/Http/Url.php', + 'Nette\\Http\\UrlImmutable' => $vendorDir . '/nette/http/src/Http/UrlImmutable.php', + 'Nette\\Http\\UrlScript' => $vendorDir . '/nette/http/src/Http/UrlScript.php', + 'Nette\\Http\\UserStorage' => $vendorDir . '/nette/http/src/Http/UserStorage.php', + 'Nette\\IOException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\Loaders\\RobotLoader' => $vendorDir . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/compatibility.php', + 'Nette\\Localization\\Translator' => $vendorDir . '/nette/utils/src/Translator.php', + 'Nette\\Mail\\DkimSigner' => $vendorDir . '/nette/mail/src/Mail/DkimSigner.php', + 'Nette\\Mail\\FallbackMailer' => $vendorDir . '/nette/mail/src/Mail/FallbackMailer.php', + 'Nette\\Mail\\FallbackMailerException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\IMailer' => $vendorDir . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Mailer' => $vendorDir . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Message' => $vendorDir . '/nette/mail/src/Mail/Message.php', + 'Nette\\Mail\\MimePart' => $vendorDir . '/nette/mail/src/Mail/MimePart.php', + 'Nette\\Mail\\SendException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SendmailMailer' => $vendorDir . '/nette/mail/src/Mail/SendmailMailer.php', + 'Nette\\Mail\\SignException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\Signer' => $vendorDir . '/nette/mail/src/Mail/Signer.php', + 'Nette\\Mail\\SmtpException' => $vendorDir . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SmtpMailer' => $vendorDir . '/nette/mail/src/Mail/SmtpMailer.php', + 'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Neon\\Decoder' => $vendorDir . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => $vendorDir . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => $vendorDir . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => $vendorDir . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Lexer' => $vendorDir . '/nette/neon/src/Neon/Lexer.php', + 'Nette\\Neon\\Neon' => $vendorDir . '/nette/neon/src/Neon/Neon.php', + 'Nette\\Neon\\Node' => $vendorDir . '/nette/neon/src/Neon/Node.php', + 'Nette\\Neon\\Node\\ArrayItemNode' => $vendorDir . '/nette/neon/src/Neon/Node/ArrayItemNode.php', + 'Nette\\Neon\\Node\\ArrayNode' => $vendorDir . '/nette/neon/src/Neon/Node/ArrayNode.php', + 'Nette\\Neon\\Node\\BlockArrayNode' => $vendorDir . '/nette/neon/src/Neon/Node/BlockArrayNode.php', + 'Nette\\Neon\\Node\\EntityChainNode' => $vendorDir . '/nette/neon/src/Neon/Node/EntityChainNode.php', + 'Nette\\Neon\\Node\\EntityNode' => $vendorDir . '/nette/neon/src/Neon/Node/EntityNode.php', + 'Nette\\Neon\\Node\\InlineArrayNode' => $vendorDir . '/nette/neon/src/Neon/Node/InlineArrayNode.php', + 'Nette\\Neon\\Node\\LiteralNode' => $vendorDir . '/nette/neon/src/Neon/Node/LiteralNode.php', + 'Nette\\Neon\\Node\\StringNode' => $vendorDir . '/nette/neon/src/Neon/Node/StringNode.php', + 'Nette\\Neon\\Parser' => $vendorDir . '/nette/neon/src/Neon/Parser.php', + 'Nette\\Neon\\Token' => $vendorDir . '/nette/neon/src/Neon/Token.php', + 'Nette\\Neon\\TokenStream' => $vendorDir . '/nette/neon/src/Neon/TokenStream.php', + 'Nette\\Neon\\Traverser' => $vendorDir . '/nette/neon/src/Neon/Traverser.php', + 'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\PhpGenerator\\Attribute' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Attribute.php', + 'Nette\\PhpGenerator\\ClassLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassLike.php', + 'Nette\\PhpGenerator\\ClassManipulator' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassManipulator.php', + 'Nette\\PhpGenerator\\ClassType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Dumper' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Dumper.php', + 'Nette\\PhpGenerator\\EnumCase' => $vendorDir . '/nette/php-generator/src/PhpGenerator/EnumCase.php', + 'Nette\\PhpGenerator\\EnumType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/EnumType.php', + 'Nette\\PhpGenerator\\Extractor' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Extractor.php', + 'Nette\\PhpGenerator\\Factory' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => $vendorDir . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\InterfaceType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/InterfaceType.php', + 'Nette\\PhpGenerator\\Literal' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Literal.php', + 'Nette\\PhpGenerator\\Method' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Printer' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Printer.php', + 'Nette\\PhpGenerator\\PromotedParameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PromotedParameter.php', + 'Nette\\PhpGenerator\\Property' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\PropertyAccessMode' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PropertyAccessMode.php', + 'Nette\\PhpGenerator\\PropertyHook' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PropertyHook.php', + 'Nette\\PhpGenerator\\PropertyHookType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PropertyHookType.php', + 'Nette\\PhpGenerator\\PsrPrinter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php', + 'Nette\\PhpGenerator\\TraitType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/TraitType.php', + 'Nette\\PhpGenerator\\TraitUse' => $vendorDir . '/nette/php-generator/src/PhpGenerator/TraitUse.php', + 'Nette\\PhpGenerator\\Traits\\AttributeAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\ConstantsAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/ConstantsAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\MethodsAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/MethodsAware.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertiesAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/PropertiesAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertyLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/PropertyLike.php', + 'Nette\\PhpGenerator\\Traits\\TraitsAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/TraitsAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\PhpGenerator\\Type' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Type.php', + 'Nette\\PhpGenerator\\Visibility' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Visibility.php', + 'Nette\\Routing\\Route' => $vendorDir . '/nette/routing/src/Routing/Route.php', + 'Nette\\Routing\\RouteList' => $vendorDir . '/nette/routing/src/Routing/RouteList.php', + 'Nette\\Routing\\Router' => $vendorDir . '/nette/routing/src/Routing/Router.php', + 'Nette\\Routing\\SimpleRouter' => $vendorDir . '/nette/routing/src/Routing/SimpleRouter.php', + 'Nette\\Schema\\Context' => $vendorDir . '/nette/schema/src/Schema/Context.php', + 'Nette\\Schema\\DynamicParameter' => $vendorDir . '/nette/schema/src/Schema/DynamicParameter.php', + 'Nette\\Schema\\Elements\\AnyOf' => $vendorDir . '/nette/schema/src/Schema/Elements/AnyOf.php', + 'Nette\\Schema\\Elements\\Base' => $vendorDir . '/nette/schema/src/Schema/Elements/Base.php', + 'Nette\\Schema\\Elements\\Structure' => $vendorDir . '/nette/schema/src/Schema/Elements/Structure.php', + 'Nette\\Schema\\Elements\\Type' => $vendorDir . '/nette/schema/src/Schema/Elements/Type.php', + 'Nette\\Schema\\Expect' => $vendorDir . '/nette/schema/src/Schema/Expect.php', + 'Nette\\Schema\\Helpers' => $vendorDir . '/nette/schema/src/Schema/Helpers.php', + 'Nette\\Schema\\Message' => $vendorDir . '/nette/schema/src/Schema/Message.php', + 'Nette\\Schema\\Processor' => $vendorDir . '/nette/schema/src/Schema/Processor.php', + 'Nette\\Schema\\Schema' => $vendorDir . '/nette/schema/src/Schema/Schema.php', + 'Nette\\Schema\\ValidationException' => $vendorDir . '/nette/schema/src/Schema/ValidationException.php', + 'Nette\\Security\\AuthenticationException' => $vendorDir . '/nette/security/src/Security/AuthenticationException.php', + 'Nette\\Security\\Authenticator' => $vendorDir . '/nette/security/src/Security/Authenticator.php', + 'Nette\\Security\\Authorizator' => $vendorDir . '/nette/security/src/Security/Authorizator.php', + 'Nette\\Security\\IAuthenticator' => $vendorDir . '/nette/security/src/Security/IAuthenticator.php', + 'Nette\\Security\\IAuthorizator' => $vendorDir . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IIdentity' => $vendorDir . '/nette/security/src/Security/IIdentity.php', + 'Nette\\Security\\IResource' => $vendorDir . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IRole' => $vendorDir . '/nette/security/src/compatibility.php', + 'Nette\\Security\\Identity' => $vendorDir . '/nette/security/src/Security/Identity.php', + 'Nette\\Security\\IdentityHandler' => $vendorDir . '/nette/security/src/Security/IdentityHandler.php', + 'Nette\\Security\\Passwords' => $vendorDir . '/nette/security/src/Security/Passwords.php', + 'Nette\\Security\\Permission' => $vendorDir . '/nette/security/src/Security/Permission.php', + 'Nette\\Security\\Resource' => $vendorDir . '/nette/security/src/Security/Resource.php', + 'Nette\\Security\\Role' => $vendorDir . '/nette/security/src/Security/Role.php', + 'Nette\\Security\\SimpleAuthenticator' => $vendorDir . '/nette/security/src/Security/SimpleAuthenticator.php', + 'Nette\\Security\\SimpleIdentity' => $vendorDir . '/nette/security/src/Security/SimpleIdentity.php', + 'Nette\\Security\\User' => $vendorDir . '/nette/security/src/Security/User.php', + 'Nette\\Security\\UserStorage' => $vendorDir . '/nette/security/src/Security/UserStorage.php', + 'Nette\\ShouldNotHappenException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/SmartObject.php', + 'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/StaticClass.php', + 'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/exceptions.php', + 'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\FileInfo' => $vendorDir . '/nette/utils/src/Utils/FileInfo.php', + 'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => $vendorDir . '/nette/utils/src/Utils/Finder.php', + 'Nette\\Utils\\Floats' => $vendorDir . '/nette/utils/src/Utils/Floats.php', + 'Nette\\Utils\\Helpers' => $vendorDir . '/nette/utils/src/Utils/Helpers.php', + 'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/compatibility.php', + 'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageColor' => $vendorDir . '/nette/utils/src/Utils/ImageColor.php', + 'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ImageType' => $vendorDir . '/nette/utils/src/Utils/ImageType.php', + 'Nette\\Utils\\Iterables' => $vendorDir . '/nette/utils/src/Utils/Iterables.php', + 'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\ReflectionMethod' => $vendorDir . '/nette/utils/src/Utils/ReflectionMethod.php', + 'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\Type' => $vendorDir . '/nette/utils/src/Utils/Type.php', + 'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php', + 'Tester\\Assert' => $vendorDir . '/nette/tester/src/Framework/Assert.php', + 'Tester\\AssertException' => $vendorDir . '/nette/tester/src/Framework/AssertException.php', + 'Tester\\CodeCoverage\\Collector' => $vendorDir . '/nette/tester/src/CodeCoverage/Collector.php', + 'Tester\\CodeCoverage\\Generators\\AbstractGenerator' => $vendorDir . '/nette/tester/src/CodeCoverage/Generators/AbstractGenerator.php', + 'Tester\\CodeCoverage\\Generators\\CloverXMLGenerator' => $vendorDir . '/nette/tester/src/CodeCoverage/Generators/CloverXMLGenerator.php', + 'Tester\\CodeCoverage\\Generators\\HtmlGenerator' => $vendorDir . '/nette/tester/src/CodeCoverage/Generators/HtmlGenerator.php', + 'Tester\\CodeCoverage\\PhpParser' => $vendorDir . '/nette/tester/src/CodeCoverage/PhpParser.php', + 'Tester\\DataProvider' => $vendorDir . '/nette/tester/src/Framework/DataProvider.php', + 'Tester\\DomQuery' => $vendorDir . '/nette/tester/src/Framework/DomQuery.php', + 'Tester\\Dumper' => $vendorDir . '/nette/tester/src/Framework/Dumper.php', + 'Tester\\Environment' => $vendorDir . '/nette/tester/src/Framework/Environment.php', + 'Tester\\Expect' => $vendorDir . '/nette/tester/src/Framework/Expect.php', + 'Tester\\FileMock' => $vendorDir . '/nette/tester/src/Framework/FileMock.php', + 'Tester\\FileMutator' => $vendorDir . '/nette/tester/src/Framework/FileMutator.php', + 'Tester\\Helpers' => $vendorDir . '/nette/tester/src/Framework/Helpers.php', + 'Tester\\HttpAssert' => $vendorDir . '/nette/tester/src/Framework/HttpAssert.php', + 'Tester\\Runner\\CliTester' => $vendorDir . '/nette/tester/src/Runner/CliTester.php', + 'Tester\\Runner\\CommandLine' => $vendorDir . '/nette/tester/src/Runner/CommandLine.php', + 'Tester\\Runner\\InterruptException' => $vendorDir . '/nette/tester/src/Runner/exceptions.php', + 'Tester\\Runner\\Job' => $vendorDir . '/nette/tester/src/Runner/Job.php', + 'Tester\\Runner\\OutputHandler' => $vendorDir . '/nette/tester/src/Runner/OutputHandler.php', + 'Tester\\Runner\\Output\\ConsolePrinter' => $vendorDir . '/nette/tester/src/Runner/Output/ConsolePrinter.php', + 'Tester\\Runner\\Output\\JUnitPrinter' => $vendorDir . '/nette/tester/src/Runner/Output/JUnitPrinter.php', + 'Tester\\Runner\\Output\\Logger' => $vendorDir . '/nette/tester/src/Runner/Output/Logger.php', + 'Tester\\Runner\\Output\\TapPrinter' => $vendorDir . '/nette/tester/src/Runner/Output/TapPrinter.php', + 'Tester\\Runner\\PhpInterpreter' => $vendorDir . '/nette/tester/src/Runner/PhpInterpreter.php', + 'Tester\\Runner\\Runner' => $vendorDir . '/nette/tester/src/Runner/Runner.php', + 'Tester\\Runner\\Test' => $vendorDir . '/nette/tester/src/Runner/Test.php', + 'Tester\\Runner\\TestHandler' => $vendorDir . '/nette/tester/src/Runner/TestHandler.php', + 'Tester\\TestCase' => $vendorDir . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseException' => $vendorDir . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseSkippedException' => $vendorDir . '/nette/tester/src/Framework/TestCase.php', + 'Tracy\\Bar' => $vendorDir . '/tracy/tracy/src/Tracy/Bar/Bar.php', + 'Tracy\\BlueScreen' => $vendorDir . '/tracy/tracy/src/Tracy/BlueScreen/BlueScreen.php', + 'Tracy\\Bridges\\Nette\\Bridge' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/Bridge.php', + 'Tracy\\Bridges\\Nette\\MailSender' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/MailSender.php', + 'Tracy\\Bridges\\Nette\\TracyExtension' => $vendorDir . '/tracy/tracy/src/Bridges/Nette/TracyExtension.php', + 'Tracy\\Bridges\\Psr\\PsrToTracyLoggerAdapter' => $vendorDir . '/tracy/tracy/src/Bridges/Psr/PsrToTracyLoggerAdapter.php', + 'Tracy\\Bridges\\Psr\\TracyToPsrLoggerAdapter' => $vendorDir . '/tracy/tracy/src/Bridges/Psr/TracyToPsrLoggerAdapter.php', + 'Tracy\\CodeHighlighter' => $vendorDir . '/tracy/tracy/src/Tracy/BlueScreen/CodeHighlighter.php', + 'Tracy\\Debugger' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/Debugger.php', + 'Tracy\\DefaultBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/Bar/DefaultBarPanel.php', + 'Tracy\\DeferredContent' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/DeferredContent.php', + 'Tracy\\DevelopmentStrategy' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/DevelopmentStrategy.php', + 'Tracy\\Dumper' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Dumper.php', + 'Tracy\\Dumper\\Describer' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Describer.php', + 'Tracy\\Dumper\\Exposer' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Exposer.php', + 'Tracy\\Dumper\\Renderer' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Renderer.php', + 'Tracy\\Dumper\\Value' => $vendorDir . '/tracy/tracy/src/Tracy/Dumper/Value.php', + 'Tracy\\FileSession' => $vendorDir . '/tracy/tracy/src/Tracy/Session/FileSession.php', + 'Tracy\\Helpers' => $vendorDir . '/tracy/tracy/src/Tracy/Helpers.php', + 'Tracy\\IBarPanel' => $vendorDir . '/tracy/tracy/src/Tracy/Bar/IBarPanel.php', + 'Tracy\\ILogger' => $vendorDir . '/tracy/tracy/src/Tracy/Logger/ILogger.php', + 'Tracy\\Logger' => $vendorDir . '/tracy/tracy/src/Tracy/Logger/Logger.php', + 'Tracy\\NativeSession' => $vendorDir . '/tracy/tracy/src/Tracy/Session/NativeSession.php', + 'Tracy\\OutputDebugger' => $vendorDir . '/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php', + 'Tracy\\ProductionStrategy' => $vendorDir . '/tracy/tracy/src/Tracy/Debugger/ProductionStrategy.php', + 'Tracy\\SessionStorage' => $vendorDir . '/tracy/tracy/src/Tracy/Session/SessionStorage.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 0000000..0ef85dc --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,12 @@ + $vendorDir . '/phpstan/phpstan/bootstrap.php', + '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', + 'd507e002f7fce7f0c6dbf1f22edcb902' => $vendorDir . '/tracy/tracy/src/Tracy/functions.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..15a2ff3 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/tracy/tracy/src'), + 'Tester\\' => array($vendorDir . '/nette/tester/src'), + 'Symfony\\Thanks\\' => array($vendorDir . '/symfony/thanks/src'), + 'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'), + 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), + 'PHPStan\\' => array($vendorDir . '/phpstan/phpstan-nette/src'), + 'OTPHP\\' => array($vendorDir . '/spomky-labs/otphp/src'), + 'Nette\\' => array($vendorDir . '/nette/application/src', $vendorDir . '/nette/assets/src', $vendorDir . '/nette/bootstrap/src', $vendorDir . '/nette/caching/src', $vendorDir . '/nette/component-model/src', $vendorDir . '/nette/database/src', $vendorDir . '/nette/di/src', $vendorDir . '/nette/forms/src', $vendorDir . '/nette/http/src', $vendorDir . '/nette/mail/src', $vendorDir . '/nette/neon/src', $vendorDir . '/nette/php-generator/src', $vendorDir . '/nette/robot-loader/src', $vendorDir . '/nette/routing/src', $vendorDir . '/nette/schema/src', $vendorDir . '/nette/security/src', $vendorDir . '/nette/utils/src'), + 'Latte\\' => array($vendorDir . '/latte/latte/src/Latte'), + 'Endroid\\QrCode\\' => array($vendorDir . '/endroid/qr-code/src'), + 'DASPRiD\\Enum\\' => array($vendorDir . '/dasprid/enum/src'), + 'BaconQrCode\\' => array($vendorDir . '/bacon/bacon-qr-code/src'), + 'App\\' => array($baseDir . '/app'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..647379b --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,50 @@ +register(true); + + $filesToLoad = \Composer\Autoload\ComposerStaticInita1ed42372489c27598cfbf4d5ef3ac47::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); + } + + return $loader; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000..e2103d4 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,831 @@ + __DIR__ . '/..' . '/phpstan/phpstan/bootstrap.php', + '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + 'd507e002f7fce7f0c6dbf1f22edcb902' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/functions.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'T' => + array ( + 'Tracy\\' => 6, + 'Tester\\' => 7, + ), + 'S' => + array ( + 'Symfony\\Thanks\\' => 15, + ), + 'P' => + array ( + 'Psr\\Clock\\' => 10, + 'ParagonIE\\ConstantTime\\' => 23, + 'PHPStan\\' => 8, + ), + 'O' => + array ( + 'OTPHP\\' => 6, + ), + 'N' => + array ( + 'Nette\\' => 6, + ), + 'L' => + array ( + 'Latte\\' => 6, + ), + 'E' => + array ( + 'Endroid\\QrCode\\' => 15, + ), + 'D' => + array ( + 'DASPRiD\\Enum\\' => 13, + ), + 'B' => + array ( + 'BaconQrCode\\' => 12, + ), + 'A' => + array ( + 'App\\' => 4, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Tracy\\' => + array ( + 0 => __DIR__ . '/..' . '/tracy/tracy/src', + ), + 'Tester\\' => + array ( + 0 => __DIR__ . '/..' . '/nette/tester/src', + ), + 'Symfony\\Thanks\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/thanks/src', + ), + 'Psr\\Clock\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/clock/src', + ), + 'ParagonIE\\ConstantTime\\' => + array ( + 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', + ), + 'PHPStan\\' => + array ( + 0 => __DIR__ . '/..' . '/phpstan/phpstan-nette/src', + ), + 'OTPHP\\' => + array ( + 0 => __DIR__ . '/..' . '/spomky-labs/otphp/src', + ), + 'Nette\\' => + array ( + 0 => __DIR__ . '/..' . '/nette/application/src', + 1 => __DIR__ . '/..' . '/nette/assets/src', + 2 => __DIR__ . '/..' . '/nette/bootstrap/src', + 3 => __DIR__ . '/..' . '/nette/caching/src', + 4 => __DIR__ . '/..' . '/nette/component-model/src', + 5 => __DIR__ . '/..' . '/nette/database/src', + 6 => __DIR__ . '/..' . '/nette/di/src', + 7 => __DIR__ . '/..' . '/nette/forms/src', + 8 => __DIR__ . '/..' . '/nette/http/src', + 9 => __DIR__ . '/..' . '/nette/mail/src', + 10 => __DIR__ . '/..' . '/nette/neon/src', + 11 => __DIR__ . '/..' . '/nette/php-generator/src', + 12 => __DIR__ . '/..' . '/nette/robot-loader/src', + 13 => __DIR__ . '/..' . '/nette/routing/src', + 14 => __DIR__ . '/..' . '/nette/schema/src', + 15 => __DIR__ . '/..' . '/nette/security/src', + 16 => __DIR__ . '/..' . '/nette/utils/src', + ), + 'Latte\\' => + array ( + 0 => __DIR__ . '/..' . '/latte/latte/src/Latte', + ), + 'Endroid\\QrCode\\' => + array ( + 0 => __DIR__ . '/..' . '/endroid/qr-code/src', + ), + 'DASPRiD\\Enum\\' => + array ( + 0 => __DIR__ . '/..' . '/dasprid/enum/src', + ), + 'BaconQrCode\\' => + array ( + 0 => __DIR__ . '/..' . '/bacon/bacon-qr-code/src', + ), + 'App\\' => + array ( + 0 => __DIR__ . '/../..' . '/app', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'Latte\\Attributes\\TemplateFilter' => __DIR__ . '/..' . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Attributes\\TemplateFunction' => __DIR__ . '/..' . '/latte/latte/src/Latte/attributes.php', + 'Latte\\Bridges\\Tracy\\BlueScreenPanel' => __DIR__ . '/..' . '/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php', + 'Latte\\Bridges\\Tracy\\LattePanel' => __DIR__ . '/..' . '/latte/latte/src/Bridges/Tracy/LattePanel.php', + 'Latte\\Bridges\\Tracy\\TracyExtension' => __DIR__ . '/..' . '/latte/latte/src/Bridges/Tracy/TracyExtension.php', + 'Latte\\Cache' => __DIR__ . '/..' . '/latte/latte/src/Latte/Cache.php', + 'Latte\\CompileException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Compiler\\Block' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Block.php', + 'Latte\\Compiler\\Escaper' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Escaper.php', + 'Latte\\Compiler\\Node' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Node.php', + 'Latte\\Compiler\\NodeHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/NodeHelpers.php', + 'Latte\\Compiler\\NodeTraverser' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/NodeTraverser.php', + 'Latte\\Compiler\\Nodes\\AreaNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php', + 'Latte\\Compiler\\Nodes\\AuxiliaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\FragmentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\AttributeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\BogusTagNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php', + 'Latte\\Compiler\\Nodes\\Html\\CommentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ElementNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php', + 'Latte\\Compiler\\Nodes\\Html\\ExpressionAttributeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php', + 'Latte\\Compiler\\Nodes\\Html\\TagNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php', + 'Latte\\Compiler\\Nodes\\NopNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/NopNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArgumentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArgumentNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ArrayItemNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ClosureUseNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ComplexTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ExpressionNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayAccessNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayAccessNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ArrayNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AssignOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\AuxiliaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\BinaryOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CastNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClassConstantFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\CloneNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ClosureNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\ConstantFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\EmptyNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FilterCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\FunctionCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\InstanceofNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\IssetNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MatchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\MethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\NewNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PostOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PreOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\PropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticMethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\StaticPropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TemporaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\TernaryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TernaryNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\UnaryOpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Expression\\VariableNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php', + 'Latte\\Compiler\\Nodes\\Php\\FilterNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IdentifierNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\InterpolatedStringPartNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php', + 'Latte\\Compiler\\Nodes\\Php\\IntersectionTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/IntersectionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListItemNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ListNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php', + 'Latte\\Compiler\\Nodes\\Php\\MatchArmNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ModifierNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NameNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php', + 'Latte\\Compiler\\Nodes\\Php\\NullableTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\OperatorNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ParameterNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ParameterNode.php', + 'Latte\\Compiler\\Nodes\\Php\\ScalarNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\BooleanNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\FloatNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\IntegerNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\InterpolatedStringNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\NullNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php', + 'Latte\\Compiler\\Nodes\\Php\\Scalar\\StringNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/StringNode.php', + 'Latte\\Compiler\\Nodes\\Php\\SuperiorTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/SuperiorTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\UnionTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/UnionTypeNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VarLikeIdentifierNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php', + 'Latte\\Compiler\\Nodes\\Php\\VariadicPlaceholderNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php', + 'Latte\\Compiler\\Nodes\\PrintNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/PrintNode.php', + 'Latte\\Compiler\\Nodes\\StatementNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php', + 'Latte\\Compiler\\Nodes\\TemplateNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/TemplateNode.php', + 'Latte\\Compiler\\Nodes\\TextNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Nodes/TextNode.php', + 'Latte\\Compiler\\PhpHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/PhpHelpers.php', + 'Latte\\Compiler\\Position' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Position.php', + 'Latte\\Compiler\\PrintContext' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/PrintContext.php', + 'Latte\\Compiler\\Tag' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Tag.php', + 'Latte\\Compiler\\TagLexer' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TagLexer.php', + 'Latte\\Compiler\\TagParser' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TagParser.php', + 'Latte\\Compiler\\TagParserData' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TagParserData.php', + 'Latte\\Compiler\\TemplateGenerator' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateGenerator.php', + 'Latte\\Compiler\\TemplateLexer' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateLexer.php', + 'Latte\\Compiler\\TemplateParser' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateParser.php', + 'Latte\\Compiler\\TemplateParserHtml' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TemplateParserHtml.php', + 'Latte\\Compiler\\Token' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/Token.php', + 'Latte\\Compiler\\TokenStream' => __DIR__ . '/..' . '/latte/latte/src/Latte/Compiler/TokenStream.php', + 'Latte\\ContentType' => __DIR__ . '/..' . '/latte/latte/src/Latte/ContentType.php', + 'Latte\\Engine' => __DIR__ . '/..' . '/latte/latte/src/Latte/Engine.php', + 'Latte\\Essential\\AuxiliaryIterator' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/AuxiliaryIterator.php', + 'Latte\\Essential\\Blueprint' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Blueprint.php', + 'Latte\\Essential\\CachingIterator' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/CachingIterator.php', + 'Latte\\Essential\\CoreExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/CoreExtension.php', + 'Latte\\Essential\\Filters' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Filters.php', + 'Latte\\Essential\\Nodes\\BlockNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/BlockNode.php', + 'Latte\\Essential\\Nodes\\CaptureNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php', + 'Latte\\Essential\\Nodes\\ContentTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php', + 'Latte\\Essential\\Nodes\\CustomFunctionCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php', + 'Latte\\Essential\\Nodes\\DebugbreakNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php', + 'Latte\\Essential\\Nodes\\DefineNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DefineNode.php', + 'Latte\\Essential\\Nodes\\DoNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DoNode.php', + 'Latte\\Essential\\Nodes\\DumpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/DumpNode.php', + 'Latte\\Essential\\Nodes\\EmbedNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php', + 'Latte\\Essential\\Nodes\\ExtendsNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php', + 'Latte\\Essential\\Nodes\\FirstLastSepNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php', + 'Latte\\Essential\\Nodes\\ForNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ForNode.php', + 'Latte\\Essential\\Nodes\\ForeachNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php', + 'Latte\\Essential\\Nodes\\IfChangedNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php', + 'Latte\\Essential\\Nodes\\IfContentNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php', + 'Latte\\Essential\\Nodes\\IfNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IfNode.php', + 'Latte\\Essential\\Nodes\\ImportNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ImportNode.php', + 'Latte\\Essential\\Nodes\\IncludeBlockNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php', + 'Latte\\Essential\\Nodes\\IncludeFileNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php', + 'Latte\\Essential\\Nodes\\IterateWhileNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php', + 'Latte\\Essential\\Nodes\\JumpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/JumpNode.php', + 'Latte\\Essential\\Nodes\\NAttrNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php', + 'Latte\\Essential\\Nodes\\NClassNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NClassNode.php', + 'Latte\\Essential\\Nodes\\NElseNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NElseNode.php', + 'Latte\\Essential\\Nodes\\NTagNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/NTagNode.php', + 'Latte\\Essential\\Nodes\\ParametersNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/ParametersNode.php', + 'Latte\\Essential\\Nodes\\RawPhpNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/RawPhpNode.php', + 'Latte\\Essential\\Nodes\\RollbackNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/RollbackNode.php', + 'Latte\\Essential\\Nodes\\SpacelessNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/SpacelessNode.php', + 'Latte\\Essential\\Nodes\\SwitchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/SwitchNode.php', + 'Latte\\Essential\\Nodes\\TemplatePrintNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TemplatePrintNode.php', + 'Latte\\Essential\\Nodes\\TemplateTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TemplateTypeNode.php', + 'Latte\\Essential\\Nodes\\TraceNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TraceNode.php', + 'Latte\\Essential\\Nodes\\TranslateNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TranslateNode.php', + 'Latte\\Essential\\Nodes\\TryNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/TryNode.php', + 'Latte\\Essential\\Nodes\\VarNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/VarNode.php', + 'Latte\\Essential\\Nodes\\VarPrintNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/VarPrintNode.php', + 'Latte\\Essential\\Nodes\\VarTypeNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/VarTypeNode.php', + 'Latte\\Essential\\Nodes\\WhileNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Nodes/WhileNode.php', + 'Latte\\Essential\\Passes' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Passes.php', + 'Latte\\Essential\\RawPhpExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/RawPhpExtension.php', + 'Latte\\Essential\\RollbackException' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/RollbackException.php', + 'Latte\\Essential\\Tracer' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/Tracer.php', + 'Latte\\Essential\\TranslatorExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Essential/TranslatorExtension.php', + 'Latte\\Exception' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Extension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Extension.php', + 'Latte\\Helpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Helpers.php', + 'Latte\\Loader' => __DIR__ . '/..' . '/latte/latte/src/Latte/Loader.php', + 'Latte\\Loaders\\FileLoader' => __DIR__ . '/..' . '/latte/latte/src/Latte/Loaders/FileLoader.php', + 'Latte\\Loaders\\StringLoader' => __DIR__ . '/..' . '/latte/latte/src/Latte/Loaders/StringLoader.php', + 'Latte\\Policy' => __DIR__ . '/..' . '/latte/latte/src/Latte/Policy.php', + 'Latte\\PositionAwareException' => __DIR__ . '/..' . '/latte/latte/src/Latte/PositionAwareException.php', + 'Latte\\RuntimeException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Runtime\\Block' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Block.php', + 'Latte\\Runtime\\FilterExecutor' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/FilterExecutor.php', + 'Latte\\Runtime\\FilterInfo' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/FilterInfo.php', + 'Latte\\Runtime\\FunctionExecutor' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/FunctionExecutor.php', + 'Latte\\Runtime\\Helpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Helpers.php', + 'Latte\\Runtime\\Html' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Html.php', + 'Latte\\Runtime\\HtmlHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/HtmlHelpers.php', + 'Latte\\Runtime\\HtmlStringable' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/HtmlStringable.php', + 'Latte\\Runtime\\Template' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/Template.php', + 'Latte\\Runtime\\XmlHelpers' => __DIR__ . '/..' . '/latte/latte/src/Latte/Runtime/XmlHelpers.php', + 'Latte\\Sandbox\\Nodes\\FunctionCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/FunctionCallNode.php', + 'Latte\\Sandbox\\Nodes\\MethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/MethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\PropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/PropertyFetchNode.php', + 'Latte\\Sandbox\\Nodes\\SandboxNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/SandboxNode.php', + 'Latte\\Sandbox\\Nodes\\StaticMethodCallNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/StaticMethodCallNode.php', + 'Latte\\Sandbox\\Nodes\\StaticPropertyFetchNode' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/Nodes/StaticPropertyFetchNode.php', + 'Latte\\Sandbox\\RuntimeChecker' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/RuntimeChecker.php', + 'Latte\\Sandbox\\SandboxExtension' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/SandboxExtension.php', + 'Latte\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/latte/latte/src/Latte/Sandbox/SecurityPolicy.php', + 'Latte\\SecurityViolationException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\TemplateNotFoundException' => __DIR__ . '/..' . '/latte/latte/src/Latte/exceptions.php', + 'Latte\\Tools\\Linter' => __DIR__ . '/..' . '/latte/latte/src/Tools/Linter.php', + 'Latte\\Tools\\LinterExtension' => __DIR__ . '/..' . '/latte/latte/src/Tools/LinterExtension.php', + 'NetteModule\\ErrorPresenter' => __DIR__ . '/..' . '/nette/application/src/Application/ErrorPresenter.php', + 'NetteModule\\MicroPresenter' => __DIR__ . '/..' . '/nette/application/src/Application/MicroPresenter.php', + 'Nette\\Application\\AbortException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Application' => __DIR__ . '/..' . '/nette/application/src/Application/Application.php', + 'Nette\\Application\\ApplicationException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Attributes\\CrossOrigin' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/CrossOrigin.php', + 'Nette\\Application\\Attributes\\Deprecated' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Deprecated.php', + 'Nette\\Application\\Attributes\\Parameter' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Parameter.php', + 'Nette\\Application\\Attributes\\Persistent' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Persistent.php', + 'Nette\\Application\\Attributes\\Requires' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/Requires.php', + 'Nette\\Application\\Attributes\\TemplateVariable' => __DIR__ . '/..' . '/nette/application/src/Application/Attributes/TemplateVariable.php', + 'Nette\\Application\\BadRequestException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\ForbiddenRequestException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\Helpers' => __DIR__ . '/..' . '/nette/application/src/Application/Helpers.php', + 'Nette\\Application\\IPresenter' => __DIR__ . '/..' . '/nette/application/src/Application/IPresenter.php', + 'Nette\\Application\\IPresenterFactory' => __DIR__ . '/..' . '/nette/application/src/Application/IPresenterFactory.php', + 'Nette\\Application\\IResponse' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\IRouter' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\InvalidPresenterException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\LinkGenerator' => __DIR__ . '/..' . '/nette/application/src/Application/LinkGenerator.php', + 'Nette\\Application\\PresenterFactory' => __DIR__ . '/..' . '/nette/application/src/Application/PresenterFactory.php', + 'Nette\\Application\\Request' => __DIR__ . '/..' . '/nette/application/src/Application/Request.php', + 'Nette\\Application\\Response' => __DIR__ . '/..' . '/nette/application/src/Application/Response.php', + 'Nette\\Application\\Responses\\CallbackResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/CallbackResponse.php', + 'Nette\\Application\\Responses\\FileResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/FileResponse.php', + 'Nette\\Application\\Responses\\ForwardResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/ForwardResponse.php', + 'Nette\\Application\\Responses\\JsonResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/JsonResponse.php', + 'Nette\\Application\\Responses\\RedirectResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/RedirectResponse.php', + 'Nette\\Application\\Responses\\TextResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/TextResponse.php', + 'Nette\\Application\\Responses\\VoidResponse' => __DIR__ . '/..' . '/nette/application/src/Application/Responses/VoidResponse.php', + 'Nette\\Application\\Routers\\CliRouter' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/CliRouter.php', + 'Nette\\Application\\Routers\\Route' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/Route.php', + 'Nette\\Application\\Routers\\RouteList' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/RouteList.php', + 'Nette\\Application\\Routers\\SimpleRouter' => __DIR__ . '/..' . '/nette/application/src/Application/Routers/SimpleRouter.php', + 'Nette\\Application\\SwitchException' => __DIR__ . '/..' . '/nette/application/src/Application/exceptions.php', + 'Nette\\Application\\UI\\AccessPolicy' => __DIR__ . '/..' . '/nette/application/src/Application/UI/AccessPolicy.php', + 'Nette\\Application\\UI\\BadSignalException' => __DIR__ . '/..' . '/nette/application/src/Application/UI/BadSignalException.php', + 'Nette\\Application\\UI\\Component' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Component.php', + 'Nette\\Application\\UI\\ComponentReflection' => __DIR__ . '/..' . '/nette/application/src/Application/UI/ComponentReflection.php', + 'Nette\\Application\\UI\\Control' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Control.php', + 'Nette\\Application\\UI\\Form' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Form.php', + 'Nette\\Application\\UI\\IRenderable' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ISignalReceiver' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\IStatePersistent' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplate' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\ITemplateFactory' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Application\\UI\\InvalidLinkException' => __DIR__ . '/..' . '/nette/application/src/Application/UI/InvalidLinkException.php', + 'Nette\\Application\\UI\\Link' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Link.php', + 'Nette\\Application\\UI\\MethodReflection' => __DIR__ . '/..' . '/nette/application/src/Application/UI/MethodReflection.php', + 'Nette\\Application\\UI\\Multiplier' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Multiplier.php', + 'Nette\\Application\\UI\\ParameterConverter' => __DIR__ . '/..' . '/nette/application/src/Application/UI/ParameterConverter.php', + 'Nette\\Application\\UI\\Presenter' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Presenter.php', + 'Nette\\Application\\UI\\PresenterComponent' => __DIR__ . '/..' . '/nette/application/src/compatibility.php', + 'Nette\\Application\\UI\\PresenterComponentReflection' => __DIR__ . '/..' . '/nette/application/src/compatibility.php', + 'Nette\\Application\\UI\\Renderable' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Renderable.php', + 'Nette\\Application\\UI\\SignalReceiver' => __DIR__ . '/..' . '/nette/application/src/Application/UI/SignalReceiver.php', + 'Nette\\Application\\UI\\StatePersistent' => __DIR__ . '/..' . '/nette/application/src/Application/UI/StatePersistent.php', + 'Nette\\Application\\UI\\Template' => __DIR__ . '/..' . '/nette/application/src/Application/UI/Template.php', + 'Nette\\Application\\UI\\TemplateFactory' => __DIR__ . '/..' . '/nette/application/src/Application/UI/TemplateFactory.php', + 'Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Assets\\Asset' => __DIR__ . '/..' . '/nette/assets/src/Assets/Asset.php', + 'Nette\\Assets\\AssetNotFoundException' => __DIR__ . '/..' . '/nette/assets/src/Assets/exceptions.php', + 'Nette\\Assets\\AudioAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/AudioAsset.php', + 'Nette\\Assets\\EntryAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/EntryAsset.php', + 'Nette\\Assets\\FilesystemMapper' => __DIR__ . '/..' . '/nette/assets/src/Assets/FilesystemMapper.php', + 'Nette\\Assets\\FontAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/FontAsset.php', + 'Nette\\Assets\\GenericAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/GenericAsset.php', + 'Nette\\Assets\\Helpers' => __DIR__ . '/..' . '/nette/assets/src/Assets/Helpers.php', + 'Nette\\Assets\\HtmlRenderable' => __DIR__ . '/..' . '/nette/assets/src/Assets/HtmlRenderable.php', + 'Nette\\Assets\\ImageAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/ImageAsset.php', + 'Nette\\Assets\\LazyLoad' => __DIR__ . '/..' . '/nette/assets/src/Assets/LazyLoad.php', + 'Nette\\Assets\\Mapper' => __DIR__ . '/..' . '/nette/assets/src/Assets/Mapper.php', + 'Nette\\Assets\\Registry' => __DIR__ . '/..' . '/nette/assets/src/Assets/Registry.php', + 'Nette\\Assets\\ScriptAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/ScriptAsset.php', + 'Nette\\Assets\\StyleAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/StyleAsset.php', + 'Nette\\Assets\\VideoAsset' => __DIR__ . '/..' . '/nette/assets/src/Assets/VideoAsset.php', + 'Nette\\Assets\\ViteMapper' => __DIR__ . '/..' . '/nette/assets/src/Assets/ViteMapper.php', + 'Nette\\Bootstrap\\Configurator' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\Bootstrap\\Extensions\\ConstantsExtension' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Extensions/ConstantsExtension.php', + 'Nette\\Bootstrap\\Extensions\\PhpExtension' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Extensions/PhpExtension.php', + 'Nette\\Bridges\\ApplicationDI\\ApplicationExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/ApplicationExtension.php', + 'Nette\\Bridges\\ApplicationDI\\LatteExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/LatteExtension.php', + 'Nette\\Bridges\\ApplicationDI\\PresenterFactoryCallback' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php', + 'Nette\\Bridges\\ApplicationDI\\RoutingExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\DefaultTemplate' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php', + 'Nette\\Bridges\\ApplicationLatte\\ILatteFactory' => __DIR__ . '/..' . '/nette/application/src/compatibility-intf.php', + 'Nette\\Bridges\\ApplicationLatte\\LatteFactory' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\ControlNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/ControlNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\IfCurrentNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkBaseNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\LinkNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\NNonceNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetAreaNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\SnippetNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php', + 'Nette\\Bridges\\ApplicationLatte\\Nodes\\TemplatePrintNode' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetBridge' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php', + 'Nette\\Bridges\\ApplicationLatte\\SnippetRuntime' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php', + 'Nette\\Bridges\\ApplicationLatte\\Template' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/Template.php', + 'Nette\\Bridges\\ApplicationLatte\\TemplateFactory' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php', + 'Nette\\Bridges\\ApplicationLatte\\UIExtension' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/UIExtension.php', + 'Nette\\Bridges\\ApplicationLatte\\UIMacros' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/UIMacros.php', + 'Nette\\Bridges\\ApplicationLatte\\UIRuntime' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php', + 'Nette\\Bridges\\ApplicationTracy\\RoutingPanel' => __DIR__ . '/..' . '/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php', + 'Nette\\Bridges\\AssetsDI\\DIExtension' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsDI/DIExtension.php', + 'Nette\\Bridges\\AssetsLatte\\LatteExtension' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/LatteExtension.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\AssetNode' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/Nodes/AssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Nodes\\NAssetNode' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/Nodes/NAssetNode.php', + 'Nette\\Bridges\\AssetsLatte\\Runtime' => __DIR__ . '/..' . '/nette/assets/src/Bridges/AssetsLatte/Runtime.php', + 'Nette\\Bridges\\CacheDI\\CacheExtension' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheDI/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\CacheExtension' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheLatte/CacheExtension.php', + 'Nette\\Bridges\\CacheLatte\\Nodes\\CacheNode' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheLatte/Nodes/CacheNode.php', + 'Nette\\Bridges\\CacheLatte\\Runtime' => __DIR__ . '/..' . '/nette/caching/src/Bridges/CacheLatte/Runtime.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => __DIR__ . '/..' . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\DatabaseDI\\DatabaseExtension' => __DIR__ . '/..' . '/nette/database/src/Bridges/DatabaseDI/DatabaseExtension.php', + 'Nette\\Bridges\\DatabaseTracy\\ConnectionPanel' => __DIR__ . '/..' . '/nette/database/src/Bridges/DatabaseTracy/ConnectionPanel.php', + 'Nette\\Bridges\\FormsDI\\FormsExtension' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsDI/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\FormMacros' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/FormMacros.php', + 'Nette\\Bridges\\FormsLatte\\FormsExtension' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/FormsExtension.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FieldNNameNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FieldNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormContainerNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormContainerNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNNameNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNNameNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\FormPrintNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/FormPrintNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputErrorNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputErrorNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\InputNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/InputNode.php', + 'Nette\\Bridges\\FormsLatte\\Nodes\\LabelNode' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Nodes/LabelNode.php', + 'Nette\\Bridges\\FormsLatte\\Runtime' => __DIR__ . '/..' . '/nette/forms/src/Bridges/FormsLatte/Runtime.php', + 'Nette\\Bridges\\HttpDI\\HttpExtension' => __DIR__ . '/..' . '/nette/http/src/Bridges/HttpDI/HttpExtension.php', + 'Nette\\Bridges\\HttpDI\\SessionExtension' => __DIR__ . '/..' . '/nette/http/src/Bridges/HttpDI/SessionExtension.php', + 'Nette\\Bridges\\HttpTracy\\SessionPanel' => __DIR__ . '/..' . '/nette/http/src/Bridges/HttpTracy/SessionPanel.php', + 'Nette\\Bridges\\MailDI\\MailExtension' => __DIR__ . '/..' . '/nette/mail/src/Bridges/MailDI/MailExtension.php', + 'Nette\\Bridges\\Psr\\PsrCacheAdapter' => __DIR__ . '/..' . '/nette/caching/src/Bridges/Psr/PsrCacheAdapter.php', + 'Nette\\Bridges\\SecurityDI\\SecurityExtension' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityDI/SecurityExtension.php', + 'Nette\\Bridges\\SecurityHttp\\CookieStorage' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityHttp/CookieStorage.php', + 'Nette\\Bridges\\SecurityHttp\\SessionStorage' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityHttp/SessionStorage.php', + 'Nette\\Bridges\\SecurityTracy\\UserPanel' => __DIR__ . '/..' . '/nette/security/src/Bridges/SecurityTracy/UserPanel.php', + 'Nette\\Caching\\BulkReader' => __DIR__ . '/..' . '/nette/caching/src/Caching/BulkReader.php', + 'Nette\\Caching\\BulkWriter' => __DIR__ . '/..' . '/nette/caching/src/Caching/BulkWriter.php', + 'Nette\\Caching\\Cache' => __DIR__ . '/..' . '/nette/caching/src/Caching/Cache.php', + 'Nette\\Caching\\IBulkReader' => __DIR__ . '/..' . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\IStorage' => __DIR__ . '/..' . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\OutputHelper' => __DIR__ . '/..' . '/nette/caching/src/Caching/OutputHelper.php', + 'Nette\\Caching\\Storage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storage.php', + 'Nette\\Caching\\Storages\\DevNullStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/DevNullStorage.php', + 'Nette\\Caching\\Storages\\FileStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/FileStorage.php', + 'Nette\\Caching\\Storages\\IJournal' => __DIR__ . '/..' . '/nette/caching/src/compatibility.php', + 'Nette\\Caching\\Storages\\Journal' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/Journal.php', + 'Nette\\Caching\\Storages\\MemcachedStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/MemcachedStorage.php', + 'Nette\\Caching\\Storages\\MemoryStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/MemoryStorage.php', + 'Nette\\Caching\\Storages\\SQLiteJournal' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/SQLiteJournal.php', + 'Nette\\Caching\\Storages\\SQLiteStorage' => __DIR__ . '/..' . '/nette/caching/src/Caching/Storages/SQLiteStorage.php', + 'Nette\\ComponentModel\\ArrayAccess' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/ArrayAccess.php', + 'Nette\\ComponentModel\\Component' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/Component.php', + 'Nette\\ComponentModel\\Container' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/Container.php', + 'Nette\\ComponentModel\\IComponent' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/IComponent.php', + 'Nette\\ComponentModel\\IContainer' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/IContainer.php', + 'Nette\\ComponentModel\\RecursiveComponentIterator' => __DIR__ . '/..' . '/nette/component-model/src/ComponentModel/RecursiveComponentIterator.php', + 'Nette\\Configurator' => __DIR__ . '/..' . '/nette/bootstrap/src/Configurator.php', + 'Nette\\DI\\Attributes\\Inject' => __DIR__ . '/..' . '/nette/di/src/DI/Attributes/Inject.php', + 'Nette\\DI\\Autowiring' => __DIR__ . '/..' . '/nette/di/src/DI/Autowiring.php', + 'Nette\\DI\\Compiler' => __DIR__ . '/..' . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => __DIR__ . '/..' . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => __DIR__ . '/..' . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Config\\Loader' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => __DIR__ . '/..' . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => __DIR__ . '/..' . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => __DIR__ . '/..' . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\Definitions\\AccessorDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/AccessorDefinition.php', + 'Nette\\DI\\Definitions\\Definition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/Definition.php', + 'Nette\\DI\\Definitions\\FactoryDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/FactoryDefinition.php', + 'Nette\\DI\\Definitions\\ImportedDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/ImportedDefinition.php', + 'Nette\\DI\\Definitions\\LocatorDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/LocatorDefinition.php', + 'Nette\\DI\\Definitions\\Reference' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/Reference.php', + 'Nette\\DI\\Definitions\\ServiceDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/ServiceDefinition.php', + 'Nette\\DI\\Definitions\\Statement' => __DIR__ . '/..' . '/nette/di/src/DI/Definitions/Statement.php', + 'Nette\\DI\\DependencyChecker' => __DIR__ . '/..' . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\DynamicParameter' => __DIR__ . '/..' . '/nette/di/src/DI/DynamicParameter.php', + 'Nette\\DI\\Extensions\\DIExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\DefinitionSchema' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DefinitionSchema.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\ParametersExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ParametersExtension.php', + 'Nette\\DI\\Extensions\\SearchExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/SearchExtension.php', + 'Nette\\DI\\Extensions\\ServicesExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ServicesExtension.php', + 'Nette\\DI\\Helpers' => __DIR__ . '/..' . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\InvalidConfigurationException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\MissingServiceException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\NotAllowedDuringResolvingException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => __DIR__ . '/..' . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\Resolver' => __DIR__ . '/..' . '/nette/di/src/DI/Resolver.php', + 'Nette\\DI\\ServiceCreationException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => __DIR__ . '/..' . '/nette/di/src/compatibility.php', + 'Nette\\DI\\Statement' => __DIR__ . '/..' . '/nette/di/src/compatibility.php', + 'Nette\\Database\\Connection' => __DIR__ . '/..' . '/nette/database/src/Database/Connection.php', + 'Nette\\Database\\ConnectionException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\ConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Context' => __DIR__ . '/..' . '/nette/database/src/compatibility.php', + 'Nette\\Database\\Conventions' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions.php', + 'Nette\\Database\\Conventions\\AmbiguousReferenceKeyException' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions/AmbiguousReferenceKeyException.php', + 'Nette\\Database\\Conventions\\DiscoveredConventions' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions/DiscoveredConventions.php', + 'Nette\\Database\\Conventions\\StaticConventions' => __DIR__ . '/..' . '/nette/database/src/Database/Conventions/StaticConventions.php', + 'Nette\\Database\\DateTime' => __DIR__ . '/..' . '/nette/database/src/Database/DateTime.php', + 'Nette\\Database\\Driver' => __DIR__ . '/..' . '/nette/database/src/Database/Driver.php', + 'Nette\\Database\\DriverException' => __DIR__ . '/..' . '/nette/database/src/Database/DriverException.php', + 'Nette\\Database\\Drivers\\MsSqlDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/MsSqlDriver.php', + 'Nette\\Database\\Drivers\\MySqlDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/MySqlDriver.php', + 'Nette\\Database\\Drivers\\OciDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/OciDriver.php', + 'Nette\\Database\\Drivers\\OdbcDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/OdbcDriver.php', + 'Nette\\Database\\Drivers\\PgSqlDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/PgSqlDriver.php', + 'Nette\\Database\\Drivers\\SqliteDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/SqliteDriver.php', + 'Nette\\Database\\Drivers\\SqlsrvDriver' => __DIR__ . '/..' . '/nette/database/src/Database/Drivers/SqlsrvDriver.php', + 'Nette\\Database\\Explorer' => __DIR__ . '/..' . '/nette/database/src/Database/Explorer.php', + 'Nette\\Database\\ForeignKeyConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Helpers' => __DIR__ . '/..' . '/nette/database/src/Database/Helpers.php', + 'Nette\\Database\\IConventions' => __DIR__ . '/..' . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\IRow' => __DIR__ . '/..' . '/nette/database/src/Database/IRow.php', + 'Nette\\Database\\IRowContainer' => __DIR__ . '/..' . '/nette/database/src/Database/IRowContainer.php', + 'Nette\\Database\\IStructure' => __DIR__ . '/..' . '/nette/database/src/Database/IStructure.php', + 'Nette\\Database\\ISupplementalDriver' => __DIR__ . '/..' . '/nette/database/src/compatibility-intf.php', + 'Nette\\Database\\NotNullConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\Database\\Reflection' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection.php', + 'Nette\\Database\\Reflection\\Column' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/Column.php', + 'Nette\\Database\\Reflection\\ForeignKey' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/ForeignKey.php', + 'Nette\\Database\\Reflection\\Index' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/Index.php', + 'Nette\\Database\\Reflection\\Table' => __DIR__ . '/..' . '/nette/database/src/Database/Reflection/Table.php', + 'Nette\\Database\\ResultSet' => __DIR__ . '/..' . '/nette/database/src/Database/ResultSet.php', + 'Nette\\Database\\Row' => __DIR__ . '/..' . '/nette/database/src/Database/Row.php', + 'Nette\\Database\\SqlLiteral' => __DIR__ . '/..' . '/nette/database/src/Database/SqlLiteral.php', + 'Nette\\Database\\SqlPreprocessor' => __DIR__ . '/..' . '/nette/database/src/Database/SqlPreprocessor.php', + 'Nette\\Database\\Structure' => __DIR__ . '/..' . '/nette/database/src/Database/Structure.php', + 'Nette\\Database\\Table\\ActiveRow' => __DIR__ . '/..' . '/nette/database/src/Database/Table/ActiveRow.php', + 'Nette\\Database\\Table\\GroupedSelection' => __DIR__ . '/..' . '/nette/database/src/Database/Table/GroupedSelection.php', + 'Nette\\Database\\Table\\IRow' => __DIR__ . '/..' . '/nette/database/src/Database/Table/IRow.php', + 'Nette\\Database\\Table\\IRowContainer' => __DIR__ . '/..' . '/nette/database/src/Database/Table/IRowContainer.php', + 'Nette\\Database\\Table\\Selection' => __DIR__ . '/..' . '/nette/database/src/Database/Table/Selection.php', + 'Nette\\Database\\Table\\SqlBuilder' => __DIR__ . '/..' . '/nette/database/src/Database/Table/SqlBuilder.php', + 'Nette\\Database\\UniqueConstraintViolationException' => __DIR__ . '/..' . '/nette/database/src/Database/exceptions.php', + 'Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\FileNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Forms\\Blueprint' => __DIR__ . '/..' . '/nette/forms/src/Forms/Blueprint.php', + 'Nette\\Forms\\Container' => __DIR__ . '/..' . '/nette/forms/src/Forms/Container.php', + 'Nette\\Forms\\Control' => __DIR__ . '/..' . '/nette/forms/src/Forms/Control.php', + 'Nette\\Forms\\ControlGroup' => __DIR__ . '/..' . '/nette/forms/src/Forms/ControlGroup.php', + 'Nette\\Forms\\Controls\\BaseControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/BaseControl.php', + 'Nette\\Forms\\Controls\\Button' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/Button.php', + 'Nette\\Forms\\Controls\\Checkbox' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/Checkbox.php', + 'Nette\\Forms\\Controls\\CheckboxList' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/CheckboxList.php', + 'Nette\\Forms\\Controls\\ChoiceControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/ChoiceControl.php', + 'Nette\\Forms\\Controls\\ColorPicker' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/ColorPicker.php', + 'Nette\\Forms\\Controls\\CsrfProtection' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/CsrfProtection.php', + 'Nette\\Forms\\Controls\\DateTimeControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/DateTimeControl.php', + 'Nette\\Forms\\Controls\\HiddenField' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/HiddenField.php', + 'Nette\\Forms\\Controls\\ImageButton' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/ImageButton.php', + 'Nette\\Forms\\Controls\\MultiChoiceControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/MultiChoiceControl.php', + 'Nette\\Forms\\Controls\\MultiSelectBox' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/MultiSelectBox.php', + 'Nette\\Forms\\Controls\\RadioList' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/RadioList.php', + 'Nette\\Forms\\Controls\\SelectBox' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/SelectBox.php', + 'Nette\\Forms\\Controls\\SubmitButton' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/SubmitButton.php', + 'Nette\\Forms\\Controls\\TextArea' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/TextArea.php', + 'Nette\\Forms\\Controls\\TextBase' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/TextBase.php', + 'Nette\\Forms\\Controls\\TextInput' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/TextInput.php', + 'Nette\\Forms\\Controls\\UploadControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/Controls/UploadControl.php', + 'Nette\\Forms\\Form' => __DIR__ . '/..' . '/nette/forms/src/Forms/Form.php', + 'Nette\\Forms\\FormRenderer' => __DIR__ . '/..' . '/nette/forms/src/Forms/FormRenderer.php', + 'Nette\\Forms\\Helpers' => __DIR__ . '/..' . '/nette/forms/src/Forms/Helpers.php', + 'Nette\\Forms\\IControl' => __DIR__ . '/..' . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\IFormRenderer' => __DIR__ . '/..' . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\ISubmitterControl' => __DIR__ . '/..' . '/nette/forms/src/compatibility.php', + 'Nette\\Forms\\Rendering\\DataClassGenerator' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rendering/DataClassGenerator.php', + 'Nette\\Forms\\Rendering\\DefaultFormRenderer' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rendering/DefaultFormRenderer.php', + 'Nette\\Forms\\Rendering\\LatteRenderer' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rendering/LatteRenderer.php', + 'Nette\\Forms\\Rule' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rule.php', + 'Nette\\Forms\\Rules' => __DIR__ . '/..' . '/nette/forms/src/Forms/Rules.php', + 'Nette\\Forms\\SubmitterControl' => __DIR__ . '/..' . '/nette/forms/src/Forms/SubmitterControl.php', + 'Nette\\Forms\\Validator' => __DIR__ . '/..' . '/nette/forms/src/Forms/Validator.php', + 'Nette\\HtmlStringable' => __DIR__ . '/..' . '/nette/utils/src/HtmlStringable.php', + 'Nette\\Http\\Context' => __DIR__ . '/..' . '/nette/http/src/Http/Context.php', + 'Nette\\Http\\FileUpload' => __DIR__ . '/..' . '/nette/http/src/Http/FileUpload.php', + 'Nette\\Http\\Helpers' => __DIR__ . '/..' . '/nette/http/src/Http/Helpers.php', + 'Nette\\Http\\IRequest' => __DIR__ . '/..' . '/nette/http/src/Http/IRequest.php', + 'Nette\\Http\\IResponse' => __DIR__ . '/..' . '/nette/http/src/Http/IResponse.php', + 'Nette\\Http\\Request' => __DIR__ . '/..' . '/nette/http/src/Http/Request.php', + 'Nette\\Http\\RequestFactory' => __DIR__ . '/..' . '/nette/http/src/Http/RequestFactory.php', + 'Nette\\Http\\Response' => __DIR__ . '/..' . '/nette/http/src/Http/Response.php', + 'Nette\\Http\\Session' => __DIR__ . '/..' . '/nette/http/src/Http/Session.php', + 'Nette\\Http\\SessionSection' => __DIR__ . '/..' . '/nette/http/src/Http/SessionSection.php', + 'Nette\\Http\\Url' => __DIR__ . '/..' . '/nette/http/src/Http/Url.php', + 'Nette\\Http\\UrlImmutable' => __DIR__ . '/..' . '/nette/http/src/Http/UrlImmutable.php', + 'Nette\\Http\\UrlScript' => __DIR__ . '/..' . '/nette/http/src/Http/UrlScript.php', + 'Nette\\Http\\UserStorage' => __DIR__ . '/..' . '/nette/http/src/Http/UserStorage.php', + 'Nette\\IOException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidArgumentException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\InvalidStateException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => __DIR__ . '/..' . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => __DIR__ . '/..' . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\Loaders\\RobotLoader' => __DIR__ . '/..' . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php', + 'Nette\\Localization\\Translator' => __DIR__ . '/..' . '/nette/utils/src/Translator.php', + 'Nette\\Mail\\DkimSigner' => __DIR__ . '/..' . '/nette/mail/src/Mail/DkimSigner.php', + 'Nette\\Mail\\FallbackMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/FallbackMailer.php', + 'Nette\\Mail\\FallbackMailerException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\IMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Mailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/Mailer.php', + 'Nette\\Mail\\Message' => __DIR__ . '/..' . '/nette/mail/src/Mail/Message.php', + 'Nette\\Mail\\MimePart' => __DIR__ . '/..' . '/nette/mail/src/Mail/MimePart.php', + 'Nette\\Mail\\SendException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SendmailMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/SendmailMailer.php', + 'Nette\\Mail\\SignException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\Signer' => __DIR__ . '/..' . '/nette/mail/src/Mail/Signer.php', + 'Nette\\Mail\\SmtpException' => __DIR__ . '/..' . '/nette/mail/src/Mail/exceptions.php', + 'Nette\\Mail\\SmtpMailer' => __DIR__ . '/..' . '/nette/mail/src/Mail/SmtpMailer.php', + 'Nette\\MemberAccessException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Neon\\Decoder' => __DIR__ . '/..' . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => __DIR__ . '/..' . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => __DIR__ . '/..' . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => __DIR__ . '/..' . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Lexer' => __DIR__ . '/..' . '/nette/neon/src/Neon/Lexer.php', + 'Nette\\Neon\\Neon' => __DIR__ . '/..' . '/nette/neon/src/Neon/Neon.php', + 'Nette\\Neon\\Node' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node.php', + 'Nette\\Neon\\Node\\ArrayItemNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/ArrayItemNode.php', + 'Nette\\Neon\\Node\\ArrayNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/ArrayNode.php', + 'Nette\\Neon\\Node\\BlockArrayNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/BlockArrayNode.php', + 'Nette\\Neon\\Node\\EntityChainNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/EntityChainNode.php', + 'Nette\\Neon\\Node\\EntityNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/EntityNode.php', + 'Nette\\Neon\\Node\\InlineArrayNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/InlineArrayNode.php', + 'Nette\\Neon\\Node\\LiteralNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/LiteralNode.php', + 'Nette\\Neon\\Node\\StringNode' => __DIR__ . '/..' . '/nette/neon/src/Neon/Node/StringNode.php', + 'Nette\\Neon\\Parser' => __DIR__ . '/..' . '/nette/neon/src/Neon/Parser.php', + 'Nette\\Neon\\Token' => __DIR__ . '/..' . '/nette/neon/src/Neon/Token.php', + 'Nette\\Neon\\TokenStream' => __DIR__ . '/..' . '/nette/neon/src/Neon/TokenStream.php', + 'Nette\\Neon\\Traverser' => __DIR__ . '/..' . '/nette/neon/src/Neon/Traverser.php', + 'Nette\\NotImplementedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\NotSupportedException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\OutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\PhpGenerator\\Attribute' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Attribute.php', + 'Nette\\PhpGenerator\\ClassLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassLike.php', + 'Nette\\PhpGenerator\\ClassManipulator' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassManipulator.php', + 'Nette\\PhpGenerator\\ClassType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Dumper' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Dumper.php', + 'Nette\\PhpGenerator\\EnumCase' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/EnumCase.php', + 'Nette\\PhpGenerator\\EnumType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/EnumType.php', + 'Nette\\PhpGenerator\\Extractor' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Extractor.php', + 'Nette\\PhpGenerator\\Factory' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\InterfaceType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/InterfaceType.php', + 'Nette\\PhpGenerator\\Literal' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Literal.php', + 'Nette\\PhpGenerator\\Method' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Printer' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Printer.php', + 'Nette\\PhpGenerator\\PromotedParameter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PromotedParameter.php', + 'Nette\\PhpGenerator\\Property' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\PropertyAccessMode' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PropertyAccessMode.php', + 'Nette\\PhpGenerator\\PropertyHook' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PropertyHook.php', + 'Nette\\PhpGenerator\\PropertyHookType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PropertyHookType.php', + 'Nette\\PhpGenerator\\PsrPrinter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php', + 'Nette\\PhpGenerator\\TraitType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/TraitType.php', + 'Nette\\PhpGenerator\\TraitUse' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/TraitUse.php', + 'Nette\\PhpGenerator\\Traits\\AttributeAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/AttributeAware.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\ConstantsAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/ConstantsAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\MethodsAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/MethodsAware.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertiesAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/PropertiesAware.php', + 'Nette\\PhpGenerator\\Traits\\PropertyLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/PropertyLike.php', + 'Nette\\PhpGenerator\\Traits\\TraitsAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/TraitsAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\PhpGenerator\\Type' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Type.php', + 'Nette\\PhpGenerator\\Visibility' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Visibility.php', + 'Nette\\Routing\\Route' => __DIR__ . '/..' . '/nette/routing/src/Routing/Route.php', + 'Nette\\Routing\\RouteList' => __DIR__ . '/..' . '/nette/routing/src/Routing/RouteList.php', + 'Nette\\Routing\\Router' => __DIR__ . '/..' . '/nette/routing/src/Routing/Router.php', + 'Nette\\Routing\\SimpleRouter' => __DIR__ . '/..' . '/nette/routing/src/Routing/SimpleRouter.php', + 'Nette\\Schema\\Context' => __DIR__ . '/..' . '/nette/schema/src/Schema/Context.php', + 'Nette\\Schema\\DynamicParameter' => __DIR__ . '/..' . '/nette/schema/src/Schema/DynamicParameter.php', + 'Nette\\Schema\\Elements\\AnyOf' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/AnyOf.php', + 'Nette\\Schema\\Elements\\Base' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Base.php', + 'Nette\\Schema\\Elements\\Structure' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Structure.php', + 'Nette\\Schema\\Elements\\Type' => __DIR__ . '/..' . '/nette/schema/src/Schema/Elements/Type.php', + 'Nette\\Schema\\Expect' => __DIR__ . '/..' . '/nette/schema/src/Schema/Expect.php', + 'Nette\\Schema\\Helpers' => __DIR__ . '/..' . '/nette/schema/src/Schema/Helpers.php', + 'Nette\\Schema\\Message' => __DIR__ . '/..' . '/nette/schema/src/Schema/Message.php', + 'Nette\\Schema\\Processor' => __DIR__ . '/..' . '/nette/schema/src/Schema/Processor.php', + 'Nette\\Schema\\Schema' => __DIR__ . '/..' . '/nette/schema/src/Schema/Schema.php', + 'Nette\\Schema\\ValidationException' => __DIR__ . '/..' . '/nette/schema/src/Schema/ValidationException.php', + 'Nette\\Security\\AuthenticationException' => __DIR__ . '/..' . '/nette/security/src/Security/AuthenticationException.php', + 'Nette\\Security\\Authenticator' => __DIR__ . '/..' . '/nette/security/src/Security/Authenticator.php', + 'Nette\\Security\\Authorizator' => __DIR__ . '/..' . '/nette/security/src/Security/Authorizator.php', + 'Nette\\Security\\IAuthenticator' => __DIR__ . '/..' . '/nette/security/src/Security/IAuthenticator.php', + 'Nette\\Security\\IAuthorizator' => __DIR__ . '/..' . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IIdentity' => __DIR__ . '/..' . '/nette/security/src/Security/IIdentity.php', + 'Nette\\Security\\IResource' => __DIR__ . '/..' . '/nette/security/src/compatibility.php', + 'Nette\\Security\\IRole' => __DIR__ . '/..' . '/nette/security/src/compatibility.php', + 'Nette\\Security\\Identity' => __DIR__ . '/..' . '/nette/security/src/Security/Identity.php', + 'Nette\\Security\\IdentityHandler' => __DIR__ . '/..' . '/nette/security/src/Security/IdentityHandler.php', + 'Nette\\Security\\Passwords' => __DIR__ . '/..' . '/nette/security/src/Security/Passwords.php', + 'Nette\\Security\\Permission' => __DIR__ . '/..' . '/nette/security/src/Security/Permission.php', + 'Nette\\Security\\Resource' => __DIR__ . '/..' . '/nette/security/src/Security/Resource.php', + 'Nette\\Security\\Role' => __DIR__ . '/..' . '/nette/security/src/Security/Role.php', + 'Nette\\Security\\SimpleAuthenticator' => __DIR__ . '/..' . '/nette/security/src/Security/SimpleAuthenticator.php', + 'Nette\\Security\\SimpleIdentity' => __DIR__ . '/..' . '/nette/security/src/Security/SimpleIdentity.php', + 'Nette\\Security\\User' => __DIR__ . '/..' . '/nette/security/src/Security/User.php', + 'Nette\\Security\\UserStorage' => __DIR__ . '/..' . '/nette/security/src/Security/UserStorage.php', + 'Nette\\ShouldNotHappenException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\SmartObject' => __DIR__ . '/..' . '/nette/utils/src/SmartObject.php', + 'Nette\\StaticClass' => __DIR__ . '/..' . '/nette/utils/src/StaticClass.php', + 'Nette\\UnexpectedValueException' => __DIR__ . '/..' . '/nette/utils/src/exceptions.php', + 'Nette\\Utils\\ArrayHash' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => __DIR__ . '/..' . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => __DIR__ . '/..' . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => __DIR__ . '/..' . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\FileInfo' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileInfo.php', + 'Nette\\Utils\\FileSystem' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => __DIR__ . '/..' . '/nette/utils/src/Utils/Finder.php', + 'Nette\\Utils\\Floats' => __DIR__ . '/..' . '/nette/utils/src/Utils/Floats.php', + 'Nette\\Utils\\Helpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/Helpers.php', + 'Nette\\Utils\\Html' => __DIR__ . '/..' . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => __DIR__ . '/..' . '/nette/utils/src/compatibility.php', + 'Nette\\Utils\\Image' => __DIR__ . '/..' . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageColor' => __DIR__ . '/..' . '/nette/utils/src/Utils/ImageColor.php', + 'Nette\\Utils\\ImageException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ImageType' => __DIR__ . '/..' . '/nette/utils/src/Utils/ImageType.php', + 'Nette\\Utils\\Iterables' => __DIR__ . '/..' . '/nette/utils/src/Utils/Iterables.php', + 'Nette\\Utils\\Json' => __DIR__ . '/..' . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\Paginator' => __DIR__ . '/..' . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Random' => __DIR__ . '/..' . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => __DIR__ . '/..' . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\ReflectionMethod' => __DIR__ . '/..' . '/nette/utils/src/Utils/ReflectionMethod.php', + 'Nette\\Utils\\RegexpException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => __DIR__ . '/..' . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\Type' => __DIR__ . '/..' . '/nette/utils/src/Utils/Type.php', + 'Nette\\Utils\\UnknownImageFileException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => __DIR__ . '/..' . '/nette/utils/src/Utils/Validators.php', + 'Tester\\Assert' => __DIR__ . '/..' . '/nette/tester/src/Framework/Assert.php', + 'Tester\\AssertException' => __DIR__ . '/..' . '/nette/tester/src/Framework/AssertException.php', + 'Tester\\CodeCoverage\\Collector' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Collector.php', + 'Tester\\CodeCoverage\\Generators\\AbstractGenerator' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Generators/AbstractGenerator.php', + 'Tester\\CodeCoverage\\Generators\\CloverXMLGenerator' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Generators/CloverXMLGenerator.php', + 'Tester\\CodeCoverage\\Generators\\HtmlGenerator' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/Generators/HtmlGenerator.php', + 'Tester\\CodeCoverage\\PhpParser' => __DIR__ . '/..' . '/nette/tester/src/CodeCoverage/PhpParser.php', + 'Tester\\DataProvider' => __DIR__ . '/..' . '/nette/tester/src/Framework/DataProvider.php', + 'Tester\\DomQuery' => __DIR__ . '/..' . '/nette/tester/src/Framework/DomQuery.php', + 'Tester\\Dumper' => __DIR__ . '/..' . '/nette/tester/src/Framework/Dumper.php', + 'Tester\\Environment' => __DIR__ . '/..' . '/nette/tester/src/Framework/Environment.php', + 'Tester\\Expect' => __DIR__ . '/..' . '/nette/tester/src/Framework/Expect.php', + 'Tester\\FileMock' => __DIR__ . '/..' . '/nette/tester/src/Framework/FileMock.php', + 'Tester\\FileMutator' => __DIR__ . '/..' . '/nette/tester/src/Framework/FileMutator.php', + 'Tester\\Helpers' => __DIR__ . '/..' . '/nette/tester/src/Framework/Helpers.php', + 'Tester\\HttpAssert' => __DIR__ . '/..' . '/nette/tester/src/Framework/HttpAssert.php', + 'Tester\\Runner\\CliTester' => __DIR__ . '/..' . '/nette/tester/src/Runner/CliTester.php', + 'Tester\\Runner\\CommandLine' => __DIR__ . '/..' . '/nette/tester/src/Runner/CommandLine.php', + 'Tester\\Runner\\InterruptException' => __DIR__ . '/..' . '/nette/tester/src/Runner/exceptions.php', + 'Tester\\Runner\\Job' => __DIR__ . '/..' . '/nette/tester/src/Runner/Job.php', + 'Tester\\Runner\\OutputHandler' => __DIR__ . '/..' . '/nette/tester/src/Runner/OutputHandler.php', + 'Tester\\Runner\\Output\\ConsolePrinter' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/ConsolePrinter.php', + 'Tester\\Runner\\Output\\JUnitPrinter' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/JUnitPrinter.php', + 'Tester\\Runner\\Output\\Logger' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/Logger.php', + 'Tester\\Runner\\Output\\TapPrinter' => __DIR__ . '/..' . '/nette/tester/src/Runner/Output/TapPrinter.php', + 'Tester\\Runner\\PhpInterpreter' => __DIR__ . '/..' . '/nette/tester/src/Runner/PhpInterpreter.php', + 'Tester\\Runner\\Runner' => __DIR__ . '/..' . '/nette/tester/src/Runner/Runner.php', + 'Tester\\Runner\\Test' => __DIR__ . '/..' . '/nette/tester/src/Runner/Test.php', + 'Tester\\Runner\\TestHandler' => __DIR__ . '/..' . '/nette/tester/src/Runner/TestHandler.php', + 'Tester\\TestCase' => __DIR__ . '/..' . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseException' => __DIR__ . '/..' . '/nette/tester/src/Framework/TestCase.php', + 'Tester\\TestCaseSkippedException' => __DIR__ . '/..' . '/nette/tester/src/Framework/TestCase.php', + 'Tracy\\Bar' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Bar/Bar.php', + 'Tracy\\BlueScreen' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/BlueScreen/BlueScreen.php', + 'Tracy\\Bridges\\Nette\\Bridge' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Nette/Bridge.php', + 'Tracy\\Bridges\\Nette\\MailSender' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Nette/MailSender.php', + 'Tracy\\Bridges\\Nette\\TracyExtension' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Nette/TracyExtension.php', + 'Tracy\\Bridges\\Psr\\PsrToTracyLoggerAdapter' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Psr/PsrToTracyLoggerAdapter.php', + 'Tracy\\Bridges\\Psr\\TracyToPsrLoggerAdapter' => __DIR__ . '/..' . '/tracy/tracy/src/Bridges/Psr/TracyToPsrLoggerAdapter.php', + 'Tracy\\CodeHighlighter' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/BlueScreen/CodeHighlighter.php', + 'Tracy\\Debugger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/Debugger.php', + 'Tracy\\DefaultBarPanel' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Bar/DefaultBarPanel.php', + 'Tracy\\DeferredContent' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/DeferredContent.php', + 'Tracy\\DevelopmentStrategy' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/DevelopmentStrategy.php', + 'Tracy\\Dumper' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Dumper.php', + 'Tracy\\Dumper\\Describer' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Describer.php', + 'Tracy\\Dumper\\Exposer' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Exposer.php', + 'Tracy\\Dumper\\Renderer' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Renderer.php', + 'Tracy\\Dumper\\Value' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Dumper/Value.php', + 'Tracy\\FileSession' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Session/FileSession.php', + 'Tracy\\Helpers' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Helpers.php', + 'Tracy\\IBarPanel' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Bar/IBarPanel.php', + 'Tracy\\ILogger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Logger/ILogger.php', + 'Tracy\\Logger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Logger/Logger.php', + 'Tracy\\NativeSession' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Session/NativeSession.php', + 'Tracy\\OutputDebugger' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php', + 'Tracy\\ProductionStrategy' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Debugger/ProductionStrategy.php', + 'Tracy\\SessionStorage' => __DIR__ . '/..' . '/tracy/tracy/src/Tracy/Session/SessionStorage.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInita1ed42372489c27598cfbf4d5ef3ac47::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInita1ed42372489c27598cfbf4d5ef3ac47::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInita1ed42372489c27598cfbf4d5ef3ac47::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..f39811c --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,2251 @@ +{ + "packages": [ + { + "name": "bacon/bacon-qr-code", + "version": "v3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/36a1cb2b81493fa5b82e50bf8068bf84d1542563", + "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^8.1" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.12", + "phpunit/phpunit": "^10.5.11 || ^11.0.4", + "spatie/phpunit-snapshot-assertions": "^5.1.5", + "spatie/pixelmatch-php": "^1.2.0", + "squizlabs/php_codesniffer": "^3.9" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "time": "2025-11-19T17:15:36+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.3" + }, + "install-path": "../bacon/bacon-qr-code" + }, + { + "name": "dasprid/enum", + "version": "1.0.7", + "version_normalized": "1.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "time": "2025-09-16T12:23:56+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" + }, + "install-path": "../dasprid/enum" + }, + { + "name": "endroid/qr-code", + "version": "6.0.9", + "version_normalized": "6.0.9.0", + "source": { + "type": "git", + "url": "https://github.com/endroid/qr-code.git", + "reference": "21e888e8597440b2205e2e5c484b6c8e556bcd1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/21e888e8597440b2205e2e5c484b6c8e556bcd1a", + "reference": "21e888e8597440b2205e2e5c484b6c8e556bcd1a", + "shasum": "" + }, + "require": { + "bacon/bacon-qr-code": "^3.0", + "php": "^8.2" + }, + "require-dev": { + "endroid/quality": "dev-main", + "ext-gd": "*", + "khanamiryan/qrcode-detector-decoder": "^2.0.2", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "ext-gd": "Enables you to write PNG images", + "khanamiryan/qrcode-detector-decoder": "Enables you to use the image validator", + "roave/security-advisories": "Makes sure package versions with known security issues are not installed", + "setasign/fpdf": "Enables you to use the PDF writer" + }, + "time": "2025-07-13T19:59:45+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl" + } + ], + "description": "Endroid QR Code", + "homepage": "https://github.com/endroid/qr-code", + "keywords": [ + "code", + "endroid", + "php", + "qr", + "qrcode" + ], + "support": { + "issues": "https://github.com/endroid/qr-code/issues", + "source": "https://github.com/endroid/qr-code/tree/6.0.9" + }, + "funding": [ + { + "url": "https://github.com/endroid", + "type": "github" + } + ], + "install-path": "../endroid/qr-code" + }, + { + "name": "latte/latte", + "version": "v3.1.1", + "version_normalized": "3.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/latte.git", + "reference": "cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/latte/zipball/cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3", + "reference": "cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "require-dev": { + "nette/php-generator": "^4.0", + "nette/tester": "^2.5", + "nette/utils": "^4.0", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.10" + }, + "suggest": { + "ext-fileinfo": "to use filter |datastream", + "ext-iconv": "to use filters |reverse, |substring", + "ext-intl": "to use Latte\\Engine::setLocale()", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "nette/php-generator": "to use tag {templatePrint}", + "nette/utils": "to use filter |webalize" + }, + "time": "2025-12-18T22:30:40+00:00", + "bin": [ + "bin/latte-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Latte\\": "src/Latte" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "homepage": "https://latte.nette.org", + "keywords": [ + "context-sensitive", + "engine", + "escaping", + "html", + "nette", + "security", + "template", + "twig" + ], + "support": { + "issues": "https://github.com/nette/latte/issues", + "source": "https://github.com/nette/latte/tree/v3.1.1" + }, + "install-path": "../latte/latte" + }, + { + "name": "nette/application", + "version": "v3.2.9", + "version_normalized": "3.2.9.0", + "source": { + "type": "git", + "url": "https://github.com/nette/application.git", + "reference": "11d9d6fc53d579a3516c1574c707a5de281bc0a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/application/zipball/11d9d6fc53d579a3516c1574c707a5de281bc0a0", + "reference": "11d9d6fc53d579a3516c1574c707a5de281bc0a0", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.1", + "nette/http": "^3.3.2", + "nette/routing": "^3.1.1", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": "<2.7.1 || >=3.0.0 <3.0.18 || >=3.2", + "nette/caching": "<3.2", + "nette/di": "<3.2", + "nette/forms": "<3.2", + "nette/schema": "<1.3", + "tracy/tracy": "<2.9" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "latte/latte": "^2.10.2 || ^3.0.18", + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Latte in templates", + "nette/forms": "Allows to use Nette\\Application\\UI\\Form" + }, + "time": "2025-12-19T11:39:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🏆 Nette Application: a full-stack component-based MVC kernel for PHP that helps you write powerful and modern web applications. Write less, have cleaner code and your work will bring you joy.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "component-based", + "control", + "framework", + "mvc", + "mvp", + "nette", + "presenter", + "routing", + "seo" + ], + "support": { + "issues": "https://github.com/nette/application/issues", + "source": "https://github.com/nette/application/tree/v3.2.9" + }, + "install-path": "../nette/application" + }, + { + "name": "nette/assets", + "version": "v1.0.5", + "version_normalized": "1.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/nette/assets.git", + "reference": "d747983c8a8ee5e8508ab9b45282c869e6b1f623" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/assets/zipball/d747983c8a8ee5e8508ab9b45282c869e6b1f623", + "reference": "d747983c8a8ee5e8508ab9b45282c869e6b1f623", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/bootstrap": "<3.2.5", + "nette/http": "<3.3.2" + }, + "require-dev": { + "latte/latte": "^3.0.22", + "mockery/mockery": "^1.6@stable", + "nette/application": "^3.2", + "nette/di": "^3.2", + "nette/http": "^3.3.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Assets in templates" + }, + "time": "2025-11-24T02:49:53+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🎨 Nette Assets: elegant asset management for PHP with versioning, caching and mappers for various storage backends.", + "homepage": "https://nette.org", + "keywords": [ + "asset management", + "assets", + "nette", + "resources", + "static files", + "versioning" + ], + "support": { + "issues": "https://github.com/nette/assets/issues", + "source": "https://github.com/nette/assets/tree/v1.0.5" + }, + "install-path": "../nette/assets" + }, + { + "name": "nette/bootstrap", + "version": "v3.2.7", + "version_normalized": "3.2.7.0", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "10fdb1cb05497da39396f2ce1785cea67c8aa439" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/10fdb1cb05497da39396f2ce1785cea67c8aa439", + "reference": "10fdb1cb05497da39396f2ce1785cea67c8aa439", + "shasum": "" + }, + "require": { + "nette/di": "^3.1", + "nette/utils": "^3.2.1 || ^4.0", + "php": "8.0 - 8.5" + }, + "conflict": { + "tracy/tracy": "<2.6" + }, + "require-dev": { + "latte/latte": "^2.8 || ^3.0", + "nette/application": "^3.1", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/robot-loader": "^3.0 || ^4.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "time": "2025-08-01T02:02:03+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.2.7" + }, + "install-path": "../nette/bootstrap" + }, + { + "name": "nette/caching", + "version": "v3.4.0", + "version_normalized": "3.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/caching.git", + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/caching/zipball/a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", + "reference": "a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": "<3.0.12" + }, + "require-dev": { + "latte/latte": "^3.0.12", + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "psr/simple-cache": "^2.0 || ^3.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-pdo_sqlite": "to use SQLiteStorage or SQLiteJournal" + }, + "time": "2025-08-06T23:05:08+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⏱ Nette Caching: library with easy-to-use API and many cache backends.", + "homepage": "https://nette.org", + "keywords": [ + "cache", + "journal", + "memcached", + "nette", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/caching/issues", + "source": "https://github.com/nette/caching/tree/v3.4.0" + }, + "install-path": "../nette/caching" + }, + { + "name": "nette/component-model", + "version": "v3.1.3", + "version_normalized": "3.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/component-model.git", + "reference": "0d100ba05279a1f4b20acecaa617027fbda8ecb2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/component-model/zipball/0d100ba05279a1f4b20acecaa617027fbda8ecb2", + "reference": "0d100ba05279a1f4b20acecaa617027fbda8ecb2", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "time": "2025-11-22T18:56:33+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⚛ Nette Component Model", + "homepage": "https://nette.org", + "keywords": [ + "components", + "nette" + ], + "support": { + "issues": "https://github.com/nette/component-model/issues", + "source": "https://github.com/nette/component-model/tree/v3.1.3" + }, + "install-path": "../nette/component-model" + }, + { + "name": "nette/database", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", + "source": { + "type": "git", + "url": "https://github.com/nette/database.git", + "reference": "1a84d3e61aa33461a3d6415235b25a7cd8b3f442" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/database/zipball/1a84d3e61aa33461a3d6415235b25a7cd8b3f442", + "reference": "1a84d3e61aa33461a3d6415235b25a7cd8b3f442", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "nette/caching": "^3.2", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "time": "2025-10-30T22:06:23+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💾 Nette Database: layer with a familiar PDO-like API but much more powerful. Building queries, advanced joins, drivers for MySQL, PostgreSQL, SQLite, MS SQL Server and Oracle.", + "homepage": "https://nette.org", + "keywords": [ + "database", + "mssql", + "mysql", + "nette", + "notorm", + "oracle", + "pdo", + "postgresql", + "queries", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/database/issues", + "source": "https://github.com/nette/database/tree/v3.2.8" + }, + "install-path": "../nette/database" + }, + { + "name": "nette/di", + "version": "v3.2.5", + "version_normalized": "3.2.5.0", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "5708c328ce7658a73c96b14dd6da7b8b27bf220f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/5708c328ce7658a73c96b14dd6da7b8b27bf220f", + "reference": "5708c328ce7658a73c96b14dd6da7b8b27bf220f", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-tokenizer": "*", + "nette/neon": "^3.3", + "nette/php-generator": "^4.1.6", + "nette/robot-loader": "^4.0", + "nette/schema": "^1.2.5", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "time": "2025-08-14T22:59:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.2.5" + }, + "install-path": "../nette/di" + }, + { + "name": "nette/forms", + "version": "v3.2.8", + "version_normalized": "3.2.8.0", + "source": { + "type": "git", + "url": "https://github.com/nette/forms.git", + "reference": "3bbf691ea0eb50d9594c2109d9252f267092b91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/forms/zipball/3bbf691ea0eb50d9594c2109d9252f267092b91f", + "reference": "3bbf691ea0eb50d9594c2109d9252f267092b91f", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.1", + "nette/http": "^3.3", + "nette/utils": "^4.0.4", + "php": "8.1 - 8.5" + }, + "conflict": { + "latte/latte": ">=3.0.0 <3.0.12 || >=3.2" + }, + "require-dev": { + "latte/latte": "^2.10.2 || ^3.0.12", + "nette/application": "^3.0", + "nette/di": "^3.0", + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-intl": "to use date/time controls" + }, + "time": "2025-11-22T19:36:34+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "bootstrap", + "csrf", + "javascript", + "nette", + "validation" + ], + "support": { + "issues": "https://github.com/nette/forms/issues", + "source": "https://github.com/nette/forms/tree/v3.2.8" + }, + "install-path": "../nette/forms" + }, + { + "name": "nette/http", + "version": "v3.3.3", + "version_normalized": "3.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/http.git", + "reference": "c557f21c8cedd621dbfd7990752b1d55ef353f1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/http/zipball/c557f21c8cedd621dbfd7990752b1d55ef353f1d", + "reference": "c557f21c8cedd621dbfd7990752b1d55ef353f1d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.4", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/di": "<3.0.3", + "nette/schema": "<1.2" + }, + "require-dev": { + "nette/di": "^3.0", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "ext-fileinfo": "to detect MIME type of uploaded files by Nette\\Http\\FileUpload", + "ext-gd": "to use image function in Nette\\Http\\FileUpload", + "ext-intl": "to support punycode by Nette\\Http\\Url", + "ext-session": "to use Nette\\Http\\Session" + }, + "time": "2025-10-30T22:32:24+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🌐 Nette Http: abstraction for HTTP request, response and session. Provides careful data sanitization and utility for URL and cookies manipulation.", + "homepage": "https://nette.org", + "keywords": [ + "cookies", + "http", + "nette", + "proxy", + "request", + "response", + "security", + "session", + "url" + ], + "support": { + "issues": "https://github.com/nette/http/issues", + "source": "https://github.com/nette/http/tree/v3.3.3" + }, + "install-path": "../nette/http" + }, + { + "name": "nette/mail", + "version": "v4.0.4", + "version_normalized": "4.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/nette/mail.git", + "reference": "5f16f76ed14a32f34580811d1a07ac357352bbc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/mail/zipball/5f16f76ed14a32f34580811d1a07ac357352bbc4", + "reference": "5f16f76ed14a32f34580811d1a07ac357352bbc4", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "nette/utils": "^4.0", + "php": "8.0 - 8.5" + }, + "require-dev": { + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "ext-fileinfo": "to detect type of attached files", + "ext-openssl": "to use Nette\\Mail\\DkimSigner" + }, + "time": "2025-08-01T02:09:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📧 Nette Mail: A handy library for creating and sending emails in PHP.", + "homepage": "https://nette.org", + "keywords": [ + "mail", + "mailer", + "mime", + "nette", + "smtp" + ], + "support": { + "issues": "https://github.com/nette/mail/issues", + "source": "https://github.com/nette/mail/tree/v4.0.4" + }, + "install-path": "../nette/mail" + }, + { + "name": "nette/neon", + "version": "v3.4.7", + "version_normalized": "3.4.7.0", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "cc96bf5264d721d0c102bb976272d3d001a23e65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/cc96bf5264d721d0c102bb976272d3d001a23e65", + "reference": "cc96bf5264d721d0c102bb976272d3d001a23e65", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "8.0 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.7" + }, + "time": "2026-01-04T08:39:50+00:00", + "bin": [ + "bin/neon-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "https://neon.nette.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.4.7" + }, + "install-path": "../nette/neon" + }, + { + "name": "nette/php-generator", + "version": "v4.2.0", + "version_normalized": "4.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/4707546a1f11badd72f5d82af4f8a6bc64bd56ac", + "reference": "4707546a1f11badd72f5d82af4f8a6bc64bd56ac", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.6", + "php": "8.1 - 8.5" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/tester": "^2.4", + "nikic/php-parser": "^5.0", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" + }, + "time": "2025-08-06T18:24:31+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.5 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v4.2.0" + }, + "install-path": "../nette/php-generator" + }, + { + "name": "nette/robot-loader", + "version": "v4.1.0", + "version_normalized": "4.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/805fb81376c24755d50bdb8bc69ca4db3def71d1", + "reference": "805fb81376c24755d50bdb8bc69ca4db3def71d1", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "time": "2025-08-06T18:34:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v4.1.0" + }, + "install-path": "../nette/robot-loader" + }, + { + "name": "nette/routing", + "version": "v3.1.2", + "version_normalized": "3.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/routing.git", + "reference": "14c466f3383add0d4f78a82074d3c9841f8edf47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/routing/zipball/14c466f3383add0d4f78a82074d3c9841f8edf47", + "reference": "14c466f3383add0d4f78a82074d3c9841f8edf47", + "shasum": "" + }, + "require": { + "nette/http": "^3.2 || ~4.0.0", + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "time": "2025-10-31T00:55:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Routing: two-ways URL conversion", + "homepage": "https://nette.org", + "keywords": [ + "nette" + ], + "support": { + "issues": "https://github.com/nette/routing/issues", + "source": "https://github.com/nette/routing/tree/v3.1.2" + }, + "install-path": "../nette/routing" + }, + { + "name": "nette/schema", + "version": "v1.3.3", + "version_normalized": "1.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004", + "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.8" + }, + "time": "2025-10-30T22:57:59+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.3" + }, + "install-path": "../nette/schema" + }, + { + "name": "nette/security", + "version": "v3.2.2", + "version_normalized": "3.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/security.git", + "reference": "beca6757457281ebc9428743bec7960809f40d49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/security/zipball/beca6757457281ebc9428743bec7960809f40d49", + "reference": "beca6757457281ebc9428743bec7960809f40d49", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.5" + }, + "conflict": { + "nette/di": "<3.0-stable", + "nette/http": "<3.1.3" + }, + "require-dev": { + "mockery/mockery": "^1.6@stable", + "nette/di": "^3.1", + "nette/http": "^3.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "time": "2025-08-01T02:15:08+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔑 Nette Security: provides authentication, authorization and a role-based access control management via ACL (Access Control List)", + "homepage": "https://nette.org", + "keywords": [ + "Authentication", + "acl", + "authorization", + "nette" + ], + "support": { + "issues": "https://github.com/nette/security/issues", + "source": "https://github.com/nette/security/tree/v3.2.2" + }, + "install-path": "../nette/security" + }, + { + "name": "nette/tester", + "version": "v2.5.7", + "version_normalized": "2.5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nette/tester.git", + "reference": "dc02e7811f3491a72e87538044586cee2f483d58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tester/zipball/dc02e7811f3491a72e87538044586cee2f483d58", + "reference": "dc02e7811f3491a72e87538044586cee2f483d58", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.5" + }, + "require-dev": { + "ext-simplexml": "*", + "phpstan/phpstan-nette": "^2.0@stable" + }, + "time": "2025-11-22T18:50:53+00:00", + "bin": [ + "src/tester" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Tester\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Miloslav Hůla", + "homepage": "https://github.com/milo" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Tester: enjoyable unit testing in PHP with code coverage reporter. 🍏🍏🍎🍏", + "homepage": "https://tester.nette.org", + "keywords": [ + "Xdebug", + "assertions", + "clover", + "code coverage", + "nette", + "pcov", + "phpdbg", + "phpunit", + "testing", + "unit" + ], + "support": { + "issues": "https://github.com/nette/tester/issues", + "source": "https://github.com/nette/tester/tree/v2.5.7" + }, + "install-path": "../nette/tester" + }, + { + "name": "nette/utils", + "version": "v4.1.1", + "version_normalized": "4.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72", + "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72", + "shasum": "" + }, + "require": { + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "time": "2025-12-22T12:14:32+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.1" + }, + "install-path": "../nette/utils" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.1.3", + "version_normalized": "3.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "infection/infection": "^0", + "nikic/php-fuzzer": "^0", + "phpunit/phpunit": "^9|^10|^11", + "vimeo/psalm": "^4|^5|^6" + }, + "time": "2025-09-24T15:06:41+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "install-path": "../paragonie/constant_time_encoding" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.33", + "version_normalized": "2.1.33.0", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9e800e6bee7d5bd02784d4c6069b48032d16224f", + "reference": "9e800e6bee7d5bd02784d4c6069b48032d16224f", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "time": "2025-12-05T10:24:31+00:00", + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "install-path": "../phpstan/phpstan" + }, + { + "name": "phpstan/phpstan-nette", + "version": "2.0.7", + "version_normalized": "2.0.7.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-nette.git", + "reference": "488d326408740b28c364849316ec065c13799568" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-nette/zipball/488d326408740b28c364849316ec065c13799568", + "reference": "488d326408740b28c364849316ec065c13799568", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.12" + }, + "conflict": { + "nette/application": "<2.3.0", + "nette/component-model": "<2.3.0", + "nette/di": "<2.3.0", + "nette/forms": "<2.3.0", + "nette/http": "<2.3.0", + "nette/utils": "<2.3.0" + }, + "require-dev": { + "nette/application": "^3.0", + "nette/di": "^3.0", + "nette/forms": "^3.0", + "nette/utils": "^2.3.0 || ^3.0.0 || ^4.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0.8", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "time": "2025-12-08T10:39:26+00:00", + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Nette Framework class reflection extension for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-nette/issues", + "source": "https://github.com/phpstan/phpstan-nette/tree/2.0.7" + }, + "install-path": "../phpstan/phpstan-nette" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "time": "2022-11-25T14:36:26+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "install-path": "../psr/clock" + }, + { + "name": "spomky-labs/otphp", + "version": "11.4.2", + "version_normalized": "11.4.2.0", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/otphp.git", + "reference": "2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad", + "reference": "2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^2.0 || ^3.0", + "php": ">=8.1", + "psr/clock": "^1.0", + "symfony/deprecation-contracts": "^3.2" + }, + "require-dev": { + "symfony/error-handler": "^6.4|^7.0|^8.0" + }, + "time": "2026-01-23T10:53:01+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "OTPHP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/Spomky-Labs/otphp/contributors" + } + ], + "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator", + "homepage": "https://github.com/Spomky-Labs/otphp", + "keywords": [ + "FreeOTP", + "RFC 4226", + "RFC 6238", + "google authenticator", + "hotp", + "otp", + "totp" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/otphp/issues", + "source": "https://github.com/Spomky-Labs/otphp/tree/11.4.2" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "install-path": "../spomky-labs/otphp" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "version_normalized": "3.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "time": "2024-09-25T14:21:43+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "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" + } + ], + "install-path": "../symfony/deprecation-contracts" + }, + { + "name": "symfony/thanks", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/thanks.git", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/thanks/zipball/f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "reference": "f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": ">=8.1" + }, + "time": "2025-10-30T17:38:50+00:00", + "type": "composer-plugin", + "extra": { + "class": "Symfony\\Thanks\\Thanks", + "branch-alias": { + "dev-main": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Thanks\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + } + ], + "description": "Encourages sending ⭐ and 💵 to fellow PHP package maintainers (not limited to Symfony components)!", + "support": { + "issues": "https://github.com/symfony/thanks/issues", + "source": "https://github.com/symfony/thanks/tree/v1.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/thanks" + }, + { + "name": "tracy/tracy", + "version": "v2.11.0", + "version_normalized": "2.11.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e", + "reference": "eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5 || ^3.0", + "nette/di": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/tester": "^2.2", + "nette/utils": "^3.0 || ^4.0", + "phpstan/phpstan-nette": "^2.0@stable", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "time": "2025-10-31T00:12:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.11-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/Tracy/functions.php" + ], + "psr-4": { + "Tracy\\": "src" + }, + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "support": { + "issues": "https://github.com/nette/tracy/issues", + "source": "https://github.com/nette/tracy/tree/v2.11.0" + }, + "install-path": "../tracy/tracy" + } + ], + "dev": true, + "dev-package-names": [ + "nette/tester", + "phpstan/phpstan", + "phpstan/phpstan-nette", + "symfony/thanks" + ] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 0000000..ea4c1a6 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,293 @@ + array( + 'name' => 'nette/web-project', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + 'bacon/bacon-qr-code' => array( + 'pretty_version' => 'v3.0.3', + 'version' => '3.0.3.0', + 'reference' => '36a1cb2b81493fa5b82e50bf8068bf84d1542563', + 'type' => 'library', + 'install_path' => __DIR__ . '/../bacon/bacon-qr-code', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'dasprid/enum' => array( + 'pretty_version' => '1.0.7', + 'version' => '1.0.7.0', + 'reference' => 'b5874fa9ed0043116c72162ec7f4fb50e02e7cce', + 'type' => 'library', + 'install_path' => __DIR__ . '/../dasprid/enum', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'endroid/qr-code' => array( + 'pretty_version' => '6.0.9', + 'version' => '6.0.9.0', + 'reference' => '21e888e8597440b2205e2e5c484b6c8e556bcd1a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../endroid/qr-code', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'latte/latte' => array( + 'pretty_version' => 'v3.1.1', + 'version' => '3.1.1.0', + 'reference' => 'cb98e705eeb0fd18f1f1c5cfe1a5f6217f9fa8b3', + 'type' => 'library', + 'install_path' => __DIR__ . '/../latte/latte', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/application' => array( + 'pretty_version' => 'v3.2.9', + 'version' => '3.2.9.0', + 'reference' => '11d9d6fc53d579a3516c1574c707a5de281bc0a0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/application', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/assets' => array( + 'pretty_version' => 'v1.0.5', + 'version' => '1.0.5.0', + 'reference' => 'd747983c8a8ee5e8508ab9b45282c869e6b1f623', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/assets', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/bootstrap' => array( + 'pretty_version' => 'v3.2.7', + 'version' => '3.2.7.0', + 'reference' => '10fdb1cb05497da39396f2ce1785cea67c8aa439', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/bootstrap', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/caching' => array( + 'pretty_version' => 'v3.4.0', + 'version' => '3.4.0.0', + 'reference' => 'a1c13221b350d0db0a2bd4a77c1e7b65e0aa065d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/caching', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/component-model' => array( + 'pretty_version' => 'v3.1.3', + 'version' => '3.1.3.0', + 'reference' => '0d100ba05279a1f4b20acecaa617027fbda8ecb2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/component-model', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/database' => array( + 'pretty_version' => 'v3.2.8', + 'version' => '3.2.8.0', + 'reference' => '1a84d3e61aa33461a3d6415235b25a7cd8b3f442', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/database', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/di' => array( + 'pretty_version' => 'v3.2.5', + 'version' => '3.2.5.0', + 'reference' => '5708c328ce7658a73c96b14dd6da7b8b27bf220f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/di', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/forms' => array( + 'pretty_version' => 'v3.2.8', + 'version' => '3.2.8.0', + 'reference' => '3bbf691ea0eb50d9594c2109d9252f267092b91f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/forms', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/http' => array( + 'pretty_version' => 'v3.3.3', + 'version' => '3.3.3.0', + 'reference' => 'c557f21c8cedd621dbfd7990752b1d55ef353f1d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/http', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/mail' => array( + 'pretty_version' => 'v4.0.4', + 'version' => '4.0.4.0', + 'reference' => '5f16f76ed14a32f34580811d1a07ac357352bbc4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/mail', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/neon' => array( + 'pretty_version' => 'v3.4.7', + 'version' => '3.4.7.0', + 'reference' => 'cc96bf5264d721d0c102bb976272d3d001a23e65', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/neon', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/php-generator' => array( + 'pretty_version' => 'v4.2.0', + 'version' => '4.2.0.0', + 'reference' => '4707546a1f11badd72f5d82af4f8a6bc64bd56ac', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/php-generator', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/robot-loader' => array( + 'pretty_version' => 'v4.1.0', + 'version' => '4.1.0.0', + 'reference' => '805fb81376c24755d50bdb8bc69ca4db3def71d1', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/robot-loader', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/routing' => array( + 'pretty_version' => 'v3.1.2', + 'version' => '3.1.2.0', + 'reference' => '14c466f3383add0d4f78a82074d3c9841f8edf47', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/routing', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/schema' => array( + 'pretty_version' => 'v1.3.3', + 'version' => '1.3.3.0', + 'reference' => '2befc2f42d7c715fd9d95efc31b1081e5d765004', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/schema', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/security' => array( + 'pretty_version' => 'v3.2.2', + 'version' => '3.2.2.0', + 'reference' => 'beca6757457281ebc9428743bec7960809f40d49', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/security', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/tester' => array( + 'pretty_version' => 'v2.5.7', + 'version' => '2.5.7.0', + 'reference' => 'dc02e7811f3491a72e87538044586cee2f483d58', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/tester', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'nette/utils' => array( + 'pretty_version' => 'v4.1.1', + 'version' => '4.1.1.0', + 'reference' => 'c99059c0315591f1a0db7ad6002000288ab8dc72', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nette/utils', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nette/web-project' => array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/constant_time_encoding' => array( + 'pretty_version' => 'v3.1.3', + 'version' => '3.1.3.0', + 'reference' => 'd5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpstan/phpstan' => array( + 'pretty_version' => '2.1.33', + 'version' => '2.1.33.0', + 'reference' => '9e800e6bee7d5bd02784d4c6069b48032d16224f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpstan/phpstan', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'phpstan/phpstan-nette' => array( + 'pretty_version' => '2.0.7', + 'version' => '2.0.7.0', + 'reference' => '488d326408740b28c364849316ec065c13799568', + 'type' => 'phpstan-extension', + 'install_path' => __DIR__ . '/../phpstan/phpstan-nette', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'psr/clock' => array( + 'pretty_version' => '1.0.0', + 'version' => '1.0.0.0', + 'reference' => 'e41a24703d4560fd0acb709162f73b8adfc3aa0d', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/clock', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'spomky-labs/otphp' => array( + 'pretty_version' => '11.4.2', + 'version' => '11.4.2.0', + 'reference' => '2a1b503fd1c1a5c751ab3c5cd37f2d2d26ab74ad', + 'type' => 'library', + 'install_path' => __DIR__ . '/../spomky-labs/otphp', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v3.6.0', + 'version' => '3.6.0.0', + 'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/thanks' => array( + 'pretty_version' => 'v1.4.1', + 'version' => '1.4.1.0', + 'reference' => 'f455cc9ba4e0c61dcc18ea7e52bd725ee661aa64', + 'type' => 'composer-plugin', + 'install_path' => __DIR__ . '/../symfony/thanks', + 'aliases' => array(), + 'dev_requirement' => true, + ), + 'tracy/tracy' => array( + 'pretty_version' => 'v2.11.0', + 'version' => '2.11.0.0', + 'reference' => 'eec57bcf2ff11d79f519a19da9d7ae1e2c63c42e', + 'type' => 'library', + 'install_path' => __DIR__ . '/../tracy/tracy', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 0000000..d32d90c --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 80200)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/vendor/dasprid/enum/LICENSE b/vendor/dasprid/enum/LICENSE new file mode 100644 index 0000000..d45a356 --- /dev/null +++ b/vendor/dasprid/enum/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017, Ben Scholzen 'DASPRiD' +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. 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. + +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/dasprid/enum/README.md b/vendor/dasprid/enum/README.md new file mode 100644 index 0000000..da37045 --- /dev/null +++ b/vendor/dasprid/enum/README.md @@ -0,0 +1,164 @@ +# PHP 7.1 enums + +[![Build Status](https://github.com/DASPRiD/Enum/actions/workflows/tests.yml/badge.svg)](https://github.com/DASPRiD/Enum/actions?query=workflow%3Atests) +[![Coverage Status](https://coveralls.io/repos/github/DASPRiD/Enum/badge.svg?branch=master)](https://coveralls.io/github/DASPRiD/Enum?branch=master) +[![Latest Stable Version](https://poser.pugx.org/dasprid/enum/v/stable)](https://packagist.org/packages/dasprid/enum) +[![Total Downloads](https://poser.pugx.org/dasprid/enum/downloads)](https://packagist.org/packages/dasprid/enum) +[![License](https://poser.pugx.org/dasprid/enum/license)](https://packagist.org/packages/dasprid/enum) + +It is a well known fact that PHP is missing a basic enum type, ignoring the rather incomplete `SplEnum` implementation +which is only available as a PECL extension. There are also quite a few other userland enum implementations around, +but all of them have one or another compromise. This library tries to close that gap as far as PHP allows it to. + +## Usage + +### Basics + +At its core, there is the `DASPRiD\Enum\AbstractEnum` class, which by default will work with constants like any other +enum implementation you might know. The first clear difference is that you should define all the constants as protected +(so nobody outside your class can read them but the `AbstractEnum` can still do so). The other even mightier difference +is that, for simple enums, the value of the constant doesn't matter at all. Let's have a look at a simple example: + +```php +use DASPRiD\Enum\AbstractEnum; + +/** + * @method static self MONDAY() + * @method static self TUESDAY() + * @method static self WEDNESDAY() + * @method static self THURSDAY() + * @method static self FRIDAY() + * @method static self SATURDAY() + * @method static self SUNDAY() + */ +final class WeekDay extends AbstractEnum +{ + protected const MONDAY = null; + protected const TUESDAY = null; + protected const WEDNESDAY = null; + protected const THURSDAY = null; + protected const FRIDAY = null; + protected const SATURDAY = null; + protected const SUNDAY = null; +} +``` + +If you need to provide constants for either internal use or public use, you can mark them as either private or public, +in which case they will be ignored by the enum, which only considers protected constants as valid values. As you can +see, we specifically defined the generated magic methods in a class level doc block, so anyone using this class will +automatically have proper auto-completion in their IDE. Now since you have defined the enum, you can simply use it like +that: + +```php +function tellItLikeItIs(WeekDay $weekDay) +{ + switch ($weekDay) { + case WeekDay::MONDAY(): + echo 'Mondays are bad.'; + break; + + case WeekDay::FRIDAY(): + echo 'Fridays are better.'; + break; + + case WeekDay::SATURDAY(): + case WeekDay::SUNDAY(): + echo 'Weekends are best.'; + break; + + default: + echo 'Midweek days are so-so.'; + } +} + +tellItLikeItIs(WeekDay::MONDAY()); +tellItLikeItIs(WeekDay::WEDNESDAY()); +tellItLikeItIs(WeekDay::FRIDAY()); +tellItLikeItIs(WeekDay::SATURDAY()); +tellItLikeItIs(WeekDay::SUNDAY()); +``` + +### More complex example + +Of course, all enums are singletons, which are not cloneable or serializable. Thus you can be sure that there is always +just one instance of the same type. Of course, the values of constants are not completely useless, let's have a look at +a more complex example: + +```php +use DASPRiD\Enum\AbstractEnum; + +/** + * @method static self MERCURY() + * @method static self VENUS() + * @method static self EARTH() + * @method static self MARS() + * @method static self JUPITER() + * @method static self SATURN() + * @method static self URANUS() + * @method static self NEPTUNE() + */ +final class Planet extends AbstractEnum +{ + protected const MERCURY = [3.303e+23, 2.4397e6]; + protected const VENUS = [4.869e+24, 6.0518e6]; + protected const EARTH = [5.976e+24, 6.37814e6]; + protected const MARS = [6.421e+23, 3.3972e6]; + protected const JUPITER = [1.9e+27, 7.1492e7]; + protected const SATURN = [5.688e+26, 6.0268e7]; + protected const URANUS = [8.686e+25, 2.5559e7]; + protected const NEPTUNE = [1.024e+26, 2.4746e7]; + + /** + * Universal gravitational constant. + * + * @var float + */ + private const G = 6.67300E-11; + + /** + * Mass in kilograms. + * + * @var float + */ + private $mass; + + /** + * Radius in meters. + * + * @var float + */ + private $radius; + + protected function __construct(float $mass, float $radius) + { + $this->mass = $mass; + $this->radius = $radius; + } + + public function mass() : float + { + return $this->mass; + } + + public function radius() : float + { + return $this->radius; + } + + public function surfaceGravity() : float + { + return self::G * $this->mass / ($this->radius * $this->radius); + } + + public function surfaceWeight(float $otherMass) : float + { + return $otherMass * $this->surfaceGravity(); + } +} + +$myMass = 80; + +foreach (Planet::values() as $planet) { + printf("Your weight on %s is %f\n", $planet, $planet->surfaceWeight($myMass)); +} +``` diff --git a/vendor/dasprid/enum/composer.json b/vendor/dasprid/enum/composer.json new file mode 100644 index 0000000..a099aba --- /dev/null +++ b/vendor/dasprid/enum/composer.json @@ -0,0 +1,34 @@ +{ + "name": "dasprid/enum", + "description": "PHP 7.1 enum implementation", + "license": "BSD-2-Clause", + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "keywords": [ + "enum", + "map" + ], + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" + }, + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "DASPRiD\\EnumTest\\": "test/" + } + } +} diff --git a/vendor/dasprid/enum/src/AbstractEnum.php b/vendor/dasprid/enum/src/AbstractEnum.php new file mode 100644 index 0000000..43006dc --- /dev/null +++ b/vendor/dasprid/enum/src/AbstractEnum.php @@ -0,0 +1,261 @@ +> + */ + private static $values = []; + + /** + * @var array + */ + private static $allValuesLoaded = []; + + /** + * @var array + */ + private static $constants = []; + + /** + * The constructor is private by default to avoid arbitrary enum creation. + * + * When creating your own constructor for a parameterized enum, make sure to declare it as protected, so that + * the static methods are able to construct it. Avoid making it public, as that would allow creation of + * non-singleton enum instances. + */ + private function __construct() + { + } + + /** + * Magic getter which forwards all calls to {@see self::valueOf()}. + * + * @return static + */ + final public static function __callStatic(string $name, array $arguments) : self + { + return static::valueOf($name); + } + + /** + * Returns an enum with the specified name. + * + * The name must match exactly an identifier used to declare an enum in this type (extraneous whitespace characters + * are not permitted). + * + * @return static + * @throws IllegalArgumentException if the enum has no constant with the specified name + */ + final public static function valueOf(string $name) : self + { + if (isset(self::$values[static::class][$name])) { + return self::$values[static::class][$name]; + } + + $constants = self::constants(); + + if (array_key_exists($name, $constants)) { + return self::createValue($name, $constants[$name][0], $constants[$name][1]); + } + + throw new IllegalArgumentException(sprintf('No enum constant %s::%s', static::class, $name)); + } + + /** + * @return static + */ + private static function createValue(string $name, int $ordinal, array $arguments) : self + { + $instance = new static(...$arguments); + $instance->name = $name; + $instance->ordinal = $ordinal; + self::$values[static::class][$name] = $instance; + return $instance; + } + + /** + * Obtains all possible types defined by this enum. + * + * @return static[] + */ + final public static function values() : array + { + if (isset(self::$allValuesLoaded[static::class])) { + return self::$values[static::class]; + } + + if (! isset(self::$values[static::class])) { + self::$values[static::class] = []; + } + + foreach (self::constants() as $name => $constant) { + if (array_key_exists($name, self::$values[static::class])) { + continue; + } + + static::createValue($name, $constant[0], $constant[1]); + } + + uasort(self::$values[static::class], function (self $a, self $b) { + return $a->ordinal() <=> $b->ordinal(); + }); + + self::$allValuesLoaded[static::class] = true; + return self::$values[static::class]; + } + + private static function constants() : array + { + if (isset(self::$constants[static::class])) { + return self::$constants[static::class]; + } + + self::$constants[static::class] = []; + $reflectionClass = new ReflectionClass(static::class); + $ordinal = -1; + + foreach ($reflectionClass->getReflectionConstants() as $reflectionConstant) { + if (! $reflectionConstant->isProtected()) { + continue; + } + + $value = $reflectionConstant->getValue(); + + self::$constants[static::class][$reflectionConstant->name] = [ + ++$ordinal, + is_array($value) ? $value : [] + ]; + } + + return self::$constants[static::class]; + } + + /** + * Returns the name of this enum constant, exactly as declared in its enum declaration. + * + * Most programmers should use the {@see self::__toString()} method in preference to this one, as the toString + * method may return a more user-friendly name. This method is designed primarily for use in specialized situations + * where correctness depends on getting the exact name, which will not vary from release to release. + */ + final public function name() : string + { + return $this->name; + } + + /** + * Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial + * constant is assigned an ordinal of zero). + * + * Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data + * structures. + */ + final public function ordinal() : int + { + return $this->ordinal; + } + + /** + * Compares this enum with the specified object for order. + * + * Returns negative integer, zero or positive integer as this object is less than, equal to or greater than the + * specified object. + * + * Enums are only comparable to other enums of the same type. The natural order implemented by this method is the + * order in which the constants are declared. + * + * @throws MismatchException if the passed enum is not of the same type + */ + final public function compareTo(self $other) : int + { + if (! $other instanceof static) { + throw new MismatchException(sprintf( + 'The passed enum %s is not of the same type as %s', + get_class($other), + static::class + )); + } + + return $this->ordinal - $other->ordinal; + } + + /** + * Forbid cloning enums. + * + * @throws CloneNotSupportedException + */ + final public function __clone() + { + throw new CloneNotSupportedException(); + } + + /** + * Forbid serializing enums. + * + * @throws SerializeNotSupportedException + */ + final public function __sleep() : array + { + throw new SerializeNotSupportedException(); + } + + /** + * Forbid serializing enums. + * + * @throws SerializeNotSupportedException + */ + final public function __serialize() : array + { + throw new SerializeNotSupportedException(); + } + + /** + * Forbid unserializing enums. + * + * @throws UnserializeNotSupportedException + */ + final public function __wakeup() : void + { + throw new UnserializeNotSupportedException(); + } + + /** + * Forbid unserializing enums. + * + * @throws UnserializeNotSupportedException + */ + final public function __unserialize($arg) : void + { + throw new UnserializeNotSupportedException(); + } + + /** + * Turns the enum into a string representation. + * + * You may override this method to give a more user-friendly version. + */ + public function __toString() : string + { + return $this->name; + } +} diff --git a/vendor/dasprid/enum/src/EnumMap.php b/vendor/dasprid/enum/src/EnumMap.php new file mode 100644 index 0000000..95b8856 --- /dev/null +++ b/vendor/dasprid/enum/src/EnumMap.php @@ -0,0 +1,385 @@ + + */ + private $keyUniverse; + + /** + * Array representation of this map. The ith element is the value to which universe[i] is currently mapped, or null + * if it isn't mapped to anything, or NullValue if it's mapped to null. + * + * @var array + */ + private $values; + + /** + * @var int + */ + private $size = 0; + + /** + * Creates a new enum map. + * + * @param string $keyType the type of the keys, must extend AbstractEnum + * @param string $valueType the type of the values + * @param bool $allowNullValues whether to allow null values + * @throws IllegalArgumentException when key type does not extend AbstractEnum + */ + public function __construct(string $keyType, string $valueType, bool $allowNullValues) + { + if (! is_subclass_of($keyType, AbstractEnum::class)) { + throw new IllegalArgumentException(sprintf( + 'Class %s does not extend %s', + $keyType, + AbstractEnum::class + )); + } + + $this->keyType = $keyType; + $this->valueType = $valueType; + $this->allowNullValues = $allowNullValues; + $this->keyUniverse = $keyType::values(); + $this->values = array_fill(0, count($this->keyUniverse), null); + } + + public function __serialize(): array + { + $values = []; + + foreach ($this->values as $ordinal => $value) { + if (null === $value) { + continue; + } + + $values[$ordinal] = $this->unmaskNull($value); + } + + return [ + 'keyType' => $this->keyType, + 'valueType' => $this->valueType, + 'allowNullValues' => $this->allowNullValues, + 'values' => $values, + ]; + } + + public function __unserialize(array $data): void + { + $this->unserialize(serialize($data)); + } + + /** + * Checks whether the map types match the supplied ones. + * + * You should call this method when an EnumMap is passed to you and you want to ensure that it's made up of the + * correct types. + * + * @throws ExpectationException when supplied key type mismatches local key type + * @throws ExpectationException when supplied value type mismatches local value type + * @throws ExpectationException when the supplied map allows null values, abut should not + */ + public function expect(string $keyType, string $valueType, bool $allowNullValues) : void + { + if ($keyType !== $this->keyType) { + throw new ExpectationException(sprintf( + 'Callee expected an EnumMap with key type %s, but got %s', + $keyType, + $this->keyType + )); + } + + if ($valueType !== $this->valueType) { + throw new ExpectationException(sprintf( + 'Callee expected an EnumMap with value type %s, but got %s', + $keyType, + $this->keyType + )); + } + + if ($allowNullValues !== $this->allowNullValues) { + throw new ExpectationException(sprintf( + 'Callee expected an EnumMap with nullable flag %s, but got %s', + ($allowNullValues ? 'true' : 'false'), + ($this->allowNullValues ? 'true' : 'false') + )); + } + } + + /** + * Returns the number of key-value mappings in this map. + */ + public function size() : int + { + return $this->size; + } + + /** + * Returns true if this map maps one or more keys to the specified value. + */ + public function containsValue($value) : bool + { + return in_array($this->maskNull($value), $this->values, true); + } + + /** + * Returns true if this map contains a mapping for the specified key. + */ + public function containsKey(AbstractEnum $key) : bool + { + $this->checkKeyType($key); + return null !== $this->values[$key->ordinal()]; + } + + /** + * Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. + * + * More formally, if this map contains a mapping from a key to a value, then this method returns the value; + * otherwise it returns null (there can be at most one such mapping). + * + * A return value of null does not necessarily indicate that the map contains no mapping for the key; it's also + * possible that hte map explicitly maps the key to null. The {@see self::containsKey()} operation may be used to + * distinguish these two cases. + * + * @return mixed + */ + public function get(AbstractEnum $key) + { + $this->checkKeyType($key); + return $this->unmaskNull($this->values[$key->ordinal()]); + } + + /** + * Associates the specified value with the specified key in this map. + * + * If the map previously contained a mapping for this key, the old value is replaced. + * + * @return mixed the previous value associated with the specified key, or null if there was no mapping for the key. + * (a null return can also indicate that the map previously associated null with the specified key.) + * @throws IllegalArgumentException when the passed values does not match the internal value type + */ + public function put(AbstractEnum $key, $value) + { + $this->checkKeyType($key); + + if (! $this->isValidValue($value)) { + throw new IllegalArgumentException(sprintf('Value is not of type %s', $this->valueType)); + } + + $index = $key->ordinal(); + $oldValue = $this->values[$index]; + $this->values[$index] = $this->maskNull($value); + + if (null === $oldValue) { + ++$this->size; + } + + return $this->unmaskNull($oldValue); + } + + /** + * Removes the mapping for this key frm this map if present. + * + * @return mixed the previous value associated with the specified key, or null if there was no mapping for the key. + * (a null return can also indicate that the map previously associated null with the specified key.) + */ + public function remove(AbstractEnum $key) + { + $this->checkKeyType($key); + + $index = $key->ordinal(); + $oldValue = $this->values[$index]; + $this->values[$index] = null; + + if (null !== $oldValue) { + --$this->size; + } + + return $this->unmaskNull($oldValue); + } + + /** + * Removes all mappings from this map. + */ + public function clear() : void + { + $this->values = array_fill(0, count($this->keyUniverse), null); + $this->size = 0; + } + + /** + * Compares the specified map with this map for quality. + * + * Returns true if the two maps represent the same mappings. + */ + public function equals(self $other) : bool + { + if ($this === $other) { + return true; + } + + if ($this->size !== $other->size) { + return false; + } + + return $this->values === $other->values; + } + + /** + * Returns the values contained in this map. + * + * The array will contain the values in the order their corresponding keys appear in the map, which is their natural + * order (the order in which the num constants are declared). + */ + public function values() : array + { + return array_values(array_map(function ($value) { + return $this->unmaskNull($value); + }, array_filter($this->values, function ($value) : bool { + return null !== $value; + }))); + } + + public function serialize() : string + { + return serialize($this->__serialize()); + } + + public function unserialize($serialized) : void + { + $data = unserialize($serialized); + $this->__construct($data['keyType'], $data['valueType'], $data['allowNullValues']); + + foreach ($this->keyUniverse as $key) { + if (array_key_exists($key->ordinal(), $data['values'])) { + $this->put($key, $data['values'][$key->ordinal()]); + } + } + } + + public function getIterator() : Traversable + { + foreach ($this->keyUniverse as $key) { + if (null === $this->values[$key->ordinal()]) { + continue; + } + + yield $key => $this->unmaskNull($this->values[$key->ordinal()]); + } + } + + private function maskNull($value) + { + if (null === $value) { + return NullValue::instance(); + } + + return $value; + } + + private function unmaskNull($value) + { + if ($value instanceof NullValue) { + return null; + } + + return $value; + } + + /** + * @throws IllegalArgumentException when the passed key does not match the internal key type + */ + private function checkKeyType(AbstractEnum $key) : void + { + if (get_class($key) !== $this->keyType) { + throw new IllegalArgumentException(sprintf( + 'Object of type %s is not the same type as %s', + get_class($key), + $this->keyType + )); + } + } + + private function isValidValue($value) : bool + { + if (null === $value) { + if ($this->allowNullValues) { + return true; + } + + return false; + } + + switch ($this->valueType) { + case 'mixed': + return true; + + case 'bool': + case 'boolean': + return is_bool($value); + + case 'int': + case 'integer': + return is_int($value); + + case 'float': + case 'double': + return is_float($value); + + case 'string': + return is_string($value); + + case 'object': + return is_object($value); + + case 'array': + return is_array($value); + } + + return $value instanceof $this->valueType; + } +} diff --git a/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php b/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php new file mode 100644 index 0000000..4b37dbe --- /dev/null +++ b/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php @@ -0,0 +1,10 @@ +build(); +``` + +## Usage: without using the builder + +```php +use Endroid\QrCode\Color\Color; +use Endroid\QrCode\Encoding\Encoding; +use Endroid\QrCode\ErrorCorrectionLevel; +use Endroid\QrCode\QrCode; +use Endroid\QrCode\Label\Label; +use Endroid\QrCode\Logo\Logo; +use Endroid\QrCode\RoundBlockSizeMode; +use Endroid\QrCode\Writer\PngWriter; +use Endroid\QrCode\Writer\ValidationException; + +$writer = new PngWriter(); + +// Create QR code +$qrCode = new QrCode( + data: 'Life is too short to be generating QR codes', + encoding: new Encoding('UTF-8'), + errorCorrectionLevel: ErrorCorrectionLevel::Low, + size: 300, + margin: 10, + roundBlockSizeMode: RoundBlockSizeMode::Margin, + foregroundColor: new Color(0, 0, 0), + backgroundColor: new Color(255, 255, 255) +); + +// Create generic logo +$logo = new Logo( + path: __DIR__.'/assets/bender.png', + resizeToWidth: 50, + punchoutBackground: true +); + +// Create generic label +$label = new Label( + text: 'Label', + textColor: new Color(255, 0, 0) +); + +$result = $writer->write($qrCode, $logo, $label); + +// Validate the result +$writer->validateResult($result, 'Life is too short to be generating QR codes'); +``` + +## Usage: working with results + +```php + +// Directly output the QR code +header('Content-Type: '.$result->getMimeType()); +echo $result->getString(); + +// Save it to a file +$result->saveToFile(__DIR__.'/qrcode.png'); + +// Generate a data URI to include image data inline (i.e. inside an tag) +$dataUri = $result->getDataUri(); +``` + +![QR Code](.github/example.png) + +### Writer options + +Some writers provide writer options. Each available writer option is can be +found as a constant prefixed with WRITER_OPTION_ in the writer class. + +* `PdfWriter` + * `unit`: unit of measurement (default: mm) + * `fpdf`: PDF to place the image in (default: new PDF) + * `x`: image offset (default: 0) + * `y`: image offset (default: 0) + * `link`: a URL or an identifier returned by `AddLink()`. +* `PngWriter` + * `compression_level`: compression level (0-9, default: -1 = zlib default) + * `number_of_colors`: number of colors (1-256, null for true color and transparency) +* `SvgWriter` + * `block_id`: id of the block element for external reference (default: block) + * `exclude_xml_declaration`: exclude XML declaration (default: false) + * `exclude_svg_width_and_height`: exclude width and height (default: false) + * `force_xlink_href`: forces xlink namespace in case of compatibility issues (default: false) + * `compact`: create using `path` element, otherwise use `defs` and `use` (default: true) +* `WebPWriter` + * `quality`: image quality (0-100, default: 80) + +You can provide any writer options like this. + +```php +use Endroid\QrCode\Writer\SvgWriter; + +$builder = new Builder( + writer: new SvgWriter(), + writerOptions: [ + SvgWriter::WRITER_OPTION_EXCLUDE_XML_DECLARATION => true + ] +); +``` + +### Encoding + +If you use a barcode scanner you can have some troubles while reading the +generated QR codes. Depending on the encoding you chose you will have an extra +amount of data corresponding to the ECI block. Some barcode scanner are not +programmed to interpret this block of information. To ensure a maximum +compatibility you can use the `ISO-8859-1` encoding that is the default +encoding used by barcode scanners (if your character set supports it, +i.e. no Chinese characters are present). + +### Round block size mode + +By default block sizes are rounded to guarantee sharp images and improve +readability. However some other rounding variants are available. + +* `margin (default)`: the size of the QR code is shrunk if necessary but the size + of the final image remains unchanged due to additional margin being added. +* `enlarge`: the size of the QR code and the final image are enlarged when + rounding differences occur. +* `shrink`: the size of the QR code and the final image are + shrunk when rounding differences occur. +* `none`: No rounding. This mode can be used when blocks don't need to be rounded + to pixels (for instance SVG). + +## Readability + +The readability of a QR code is primarily determined by the size, the input +length, the error correction level and any possible logo over the image so you +can tweak these parameters if you are looking for optimal results. You can also +check $qrCode->getRoundBlockSize() value to see if block dimensions are rounded +so that the image is more sharp and readable. Please note that rounding block +size can result in additional padding to compensate for the rounding difference. +And finally the encoding (default UTF-8 to support large character sets) can be +set to `ISO-8859-1` if possible to improve readability. + +## Validating the generated QR code + +If you need to be extra sure the QR code you generated is readable and contains +the exact data you requested you can enable the validation reader, which is +disabled by default. You can do this either via the builder or directly on any +writer that supports validation. See the examples above. + +Please note that validation affects performance so only use it in case of problems. + +## Symfony integration + +The [endroid/qr-code-bundle](https://github.com/endroid/qr-code-bundle) +integrates the QR code library in Symfony for an even better experience. + +* Configure your defaults (like image size, default writer etc.) +* Support for multiple configurations and injection via aliases +* Generate QR codes for defined configurations via URL like /qr-code//Hello +* Generate QR codes or URLs directly from Twig using dedicated functions + +Read the [bundle documentation](https://github.com/endroid/qr-code-bundle) +for more information. + +## Versioning + +Version numbers follow the MAJOR.MINOR.PATCH scheme. Backwards compatibility +breaking changes will be kept to a minimum but be aware that these can occur. +Lock your dependencies for production and test your code when upgrading. + +## License + +This bundle is under the MIT license. For the full copyright and license +information please view the LICENSE file that was distributed with this source code. diff --git a/vendor/endroid/qr-code/assets/open_sans.ttf b/vendor/endroid/qr-code/assets/open_sans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..db433349b7047f72f40072630c1bc110620bf09e GIT binary patch literal 217360 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 !}#gv~NV!5|5YF|kE)J0y^zWbk4>=%|6F zy33ntw4%IFi~mIi5@F#H5DC=t8uf}S#Z!v&ic1RE28BXUsSJfa6)#wCtF~p^u#l?O z0eO(1tOyP?MELD=Km)RBA<)+2kmXB7xbwDcqlf4~djB)cr@zKqO|>VuQGqgCZaIE3 zPh2kU<-E;J^`bgJLs^!BadisA9M-epj#W!_dJhcpZBZu{FY81@5jOeF832a~R(03X2W)KY_>5w^fiM0iyS zq%u`hqg9fKkhPICljOuxNnP{%E5+Tkq7r3hd&klWarYQHQrI#Yr@Kef5#qz6X(g>3 zEAC`b-29f8QK|O_V%~l=vM$gI3^C z!Y60tXHxOrtB^`*qqJ4fEET*nk_K`bthO);LX)F!<(Xs2C;+<8w5srY( zu0@%q3gV+xX;sLVOLdx3Du!*r2e;hAbS6iRqa`(@O?lx=}0~I`prdz`0bPBzJ-?Iar*W^g&H3>}H%XNc%hQ z&qCOO`)I~fh@bt9jkl#Mb;>-SMTZT&V37&SK;U1z`MA2^}p#@GHK-TN4KYLihx- z&=`-y&Zf5NF{{N9=%EevXn7hv2H)xdTaB_JHijwG<0^W@NN@yZnJ7Ms9!%pz1R#Mv z!LKR^qfpz&-ZCrnCOYMswrx>A9AVQL%?7zDzP&0Y&lkqqj1f9Ld@vPnw@|*_%`I7$ z?M;UE{_ocr@fs~jPs8TEJtHn&hD3FIhD}Oen|LPAfn7=L_22mOQ@pUF`1j{yl$qzm zp9{VnR*}17+_mEKTOQqac!&7ZQ+u9znDdBVi*Hly=U-9z9O1new%=RZD`jRuQQbYW z*ND@_Z#FcFTOND%45O_d`Y}h6Hei&>X(>_-z)5rnuZ*@>FKGY&F!mmRQB~Rh_`9!6 z?=zW6pG-m$LI@!VA%svuZ!xrpgeD*$9T5Qm5fL#WAkvF~fDj=@mPMq=x*}MRMMQKJ z(M49#wPRTq$;`|DbMBj&B&grtpBR(Oyt(zwEic!yR+`hQ9v-nH+7mQ$5{Rw%jTou0W`yqqZpXl+JKp{;o`#6MGgfDxC6hJr~ zMf?5vWlsUlxa`9Y44%csDMRt_OJ1k6;g^0}9tpDLo{D=%Ek-cNmisDZk69G_TOqs9 z?_Pw1Y%EZ7d(C`ipB5L=V|MwHO-S%SXh_-IvZb4Tdv1dGXyHHK+dVF{u;4OL2KS@$ zogb?0{Ao@Z-pJ0~`u?1m{QW59-10u_=i=|DHTgW>S*`ua0qv}{;13WV=e}S*f)RWK zbF>!x`~jRr9>oH?iC0J!I+glUbO|1Z0}++Y(p-Ww!QwSa#$?1(dLe;)|YRv10P(7%!bcbo6Tf!QQ|Gx(fNYeC=T5r zoHeeKvfIL%kElsAXhXXj$KnZo_p;mm%TJ4TvEhB*g1#u)Lb;I5lY z|D3mw9@!N^?W#DH6Iu(G75pAPLrLEu=@rd`k4W=3Z9@b=#lR~0890MjiO9AskM>XcoaJu=E2HvNuY%&r-P)a4CO0<7zy-ICJf~* zh*4_*=AkUsc`%Az^n}<>vS1Xjy`;f6#%(WQO%N9QHF!sh6uSrtj~6n9aivA+I+smI zPL7H5#yNCy^Q`!oSYS}~s*JHa{mxt`iVHZMMmG*M{MM;Fk~pE^=FxNr4(Jn65o5zq zf~50ndViCs;*3J>X)K5-h=Kh3r_se`wUoV5y>;s!h8Pd-vvl#%ql@d(8={OsHC)H% zl+N{YP&(=7Sj{M%(!JwSh|;-Cz;1&~fO{p%U3d$e(zO=K1&7vxrO|$&1)_AVh4MPy zLPCV@v=(SLv=;gUZ@!Sm5VbRCV<4)b7KmzK5ui~-C7Uy9SIS7$+Tf>RmL@T&V`M~8 zYoFw=Pe5GM@2nr7k?^Q}O-9YBOdEBXHtMK!Ou{ieC-pPw7^$RYoYvY-a^-=Ezo(>TIes1(^`n0SUv`R z-lzpyIX_=Hsb91WwS=-@wKm|}C}ub{SfN`+FSh60Lh2d$9Gx;hpFh+JwA@eFp!FTK z{cwp!UxSumALUQ@*)rN!QYEt~!vg=5FQF5n({U3@T- zc};M7Q3jvehc9MvxR8Ps_G^%vJPhbY%3|1TMyH5tjBdna1n|wz4bO*7D`bU~w255U zH{YbJ*fa9%penz71OHamou~X*Id7%<_*Y*+UxaOdM^GmVm8JP!52AamMjU&W(JcE@ zeBOA3u({0^bFWH=g?zxd7ReiLvBY~NBZMn0v>GC2E(I0*p;B^7oHdL>G+umBh6V1y zaJ=>Y?Ksrc?4;T`5_P>Dv8?ZhzLYO7I(~f7=?V(Gem67%@;Ov6@hxr<;#Mv;2#I){ zrXpvl{z*J>KbP~kY>g)#;}ikdys+K}S`r`TJV9&YHZ`QR5#b4>1&H~aCunWlrarH= zp^vnYj3*xFTtRE2T>VXJBf=Hx|A8mkaoX0}D353Xa-@w4wJT*OgILgppko6k5?vOm zUD;wz(Pi4J4tf>*05(KA30i;sg#nG{O}am5a0on0k?3jEN7drc$;QAft>Nftxi__^ zE|MLfOs#LdkR$Hpr(zd0v#E${&k(40y>J_D2=q@m&f<7}8gevRSHsrS$XTYSb+JEj z1Fxa+2=mM)DEjjIW2@}U==!+1`szS3l^lO$#$Dj zFC)`YX8;boK>+RroF{O-aqlCyQ8lbB7hemU2yKFa3gB*(8$PKUQi!vXa2nbj*!0LefP=<1Y3VA!DeNmzth05~Y z7^13RUgBM{AQP_;CA)IBRhoyCgYGv`Vvw9Z%!*okQe^R)e8qPBxgc{RVQ zxb`W`K~X5|U&AerTLSrvS__;u5e!D_3EJ$=?^k?|_I1b~^oQHETI(-z8Z>RUp+8oJ zYYF{DWl^|ZWr}~y6b1@a7&EZvKpNQLL{0(Nu`}u-8WFPd+Lb0ctX7-Bpzt`-W+=BA9NbI-+Bb-s9kBY+irL06B0xRLN$4^mc#9E+8tW_ zc{no#J4%Md#!feFG(6sv0yo2v==>J&=%n-^MIAb=2&Xid+8mmG_Kg)hO{G?v7tL%K zH1zN923KxD{awv!&$)O$?Kvd7H~1ciQOhq$Rbx39A4Dt6ZsS^=7_}ymeDX5q;aUsj zVM$z!`rWh^NV3yfD95!2sZ2A{M8?4BPHSN>^I!~QHOS^74(XP>4NeJK8-sx%L{GHj z*8oWg7>DjlWZ8QVi8Q#hRjkhLb|(o|XOd1y3D{k**V_fN8G?dYG9rH+VRT3xms|pz zZjqzPlypsJ$KyU0SeM&fD}CH)38hAZNS>OL|6p@d3G{x9oVb%eq@s- zLsrWZZZFO88*HN2o1PmJlbCLh^9!<@o14S>jNB7Zv6)-7Qk-T-EWqKB_kqmP#x_nD zS*@BFIK$RWC578AHGCNY5Nm4MY@Dn@3N>t+$_DlF!cG^KT|s!F?wcj&I<UW8$9=ej~OO58uQn@g{WQqmKNX@{aWLG1%J{4>$j1&5VgEd z1~&mN0_KM?K+2dOmdWutWu4%4^h~b{@AG-z+GAP$=UR`g|E$Nd&Adm=u!|LSVV!|- zfR-Vh&^pJ_I{T3*j|>vLdWZJv!}O{PyE=@okS58L)qkw@7WFz&=E(>AcE;!Eb{@-l zHv$@PdxKl@7QnlaMZj-clx;OyY@*_DnrwE!7U}JF$>P$95&)+N_?4Rr!7+0i`%^U* zu3;^3A1Vdpva1^A0&A!@6p;6+lmFPK=6O$;E!6xWVNU#{hm^g#U zrb|k;dEMS#mGLICsaK`XY}PqT-F6)^WRND!@B8?3kr6aHdl&_7l60O{3*#`4t8Pe_ z;j+BwyS+oo}7TakgiX&A~>fi(wO`w3&Kg@h_jy`f5Hq@}_cs8`gG) zw!Tr$%`JLdhUXSLHt2tRH>0;TZ-MiEt%ci!)mjS?EkLs=a^A1Ca9bR2AvPj=YhxhY zRBNGJSgy4YwSZ}3Al|RFP>xN-If`l8!Uxe71_)cx0@>NLK@jiPER##4Z47|@g`Uuc zK~LP`zhr}jtKn8O6}O=kvW#mZ89Y&ICG2IQR$xm5@`g4RZUumellq4(ZM@uD`y_w; z7ydd-+xjw2;q8eBuzm#fOtWhqIZr+uk~Gc(a9z<8gx*e1XhuY|jem_jqTm9bYHdU< z47XTSSwARIXd!CT&{`m6xdZiqoUwmR zB%T1bf*gfj+>w3KS|H7dw*ZN_`yaKyH7;raGP7_+o9iuYkbJ4NQC9z*)<%@xZW#qD zd$bX?ko*K$_%b}RaK@I}5JhO!0nDstCGahHtRG@xNa*D$t_>OE$aQ6Rj~aGaeQEN7`52;b3jEWjoE1`p?xoG*lann5SE9irDuL7_lf~4t5=y#5aNwo|0AZtS zVQ!d%TcYXlZX_r2jCJx)`1D$u2Tug>zyRH&v}eaVZ~NE3b{)R`es9c#4r2$fc=hY; zs>i+DH35ax`*m1;>R@(hmy}5ltX~`~I{Ftx0pp+I(bpg*I2LyER`7ndaVm1G&I43^ zy&+A=f)T`+>Jfz`$=EtK!`4zX#v%g6=&{A7+G1mEsgfa4HV_62IkI47;A!jdtdMxy zAX(BMNCe})3#1!!RDMQ5*^n&V1knedyE__|>4uLh9Gu=(nmAGP>^~6NUcF!ROrC$& zxP=J^<8p1Sjep&gH^Fx{WpCFR7rPb|bnQ@FSgLGT+O95>tyX8qAGCRF{Jpb-ZP|hL zt6Nvasul9mlJzYdt#;<9|1Iv&p}44HM?_I``!{B9gpEBHzTaNL-K9l2uC8r6w9bl& zF*j?bYb~@*a_M{bL1cI5;vNM~vn3|0SEU7r8!0Jp+@v_{>2Tk8O);{NtHpzcH;|*x zBBk(jzLSS4hOI(Tu^;(RMF9#zWe5`G!EF&V4&5KYaWsxb1R#ENdDsW7CVQD2v-=?? zMgTkF4$WOU`q^GZ74M9{a3+G-!D<#v7(Z{``0)=+>%y0-O{wmZqs9Hm>6z61x6B4W zkB8^CNm-O#&=k=_={R=oeRqwWHFs3Ijvd?K8=OmvIO81ZF*=jN97L89hib5KbI&?I z_j|P`7+`epgw!K)@_9@QZ(~dNi8$Vdq=n>wyKpZWZ{s+g0Pld*Kk zYS0l^#jA~^6uf#2A7&O{vFwMx)`px+qh4^>&GJJwO4o=F=WF1c5fvhZDkhB(gwl{N zGr?Ewowji9(4~(dH2eBv4`sDj`mnEP$)jz4*CIme5u*E$WNzAG0YMNI#OTo+z+RYT z*1eM+9zM70ldYiJGjeP zjyN>5R~fqu&!*$q)yg$(J{F13$3WFOBEjdxH!?B{l0}N4EYRu1AuF~TC+f2L+&+G^ zX`<;_`O>l_dF|p$yFK^>`WAL6B1bha1FHr$CE&SZaiT!^jpKrMMQ{<6nGs+DZAfheNOo)|DL2uz zl|0#l`u9oAFR+cZ&KlloNO|v+yw>)+tTW}y={e~gI?h{$A0?gUEyFb5oS+EC>&m&*~pFFIPXamy7>PVm{&01TAPfl zyrQ&>HtbO3H)ZL*M?KwM=qR^o)uxq}2E~7B(hNMJCfxANFg<`)s44Xu$z$e_Shkb+A>hGTU9MVg7{!B~M zCD7XW&n@kI4*P(}d&)=RGR79to)8lo_q3F^(t(+p_GFDbgPwE+)C!x^xp6Bj;uEa@ z3R=xtlByYm7xZ(x`Zi91RtDf~@3Fi>srcRJo`z)n?2(vf6Y zKpqj)9N@JQ%ov%32!sVY2`faJQ@RmaP@^2)eDgD?OK1(g8F?DDCN__>&h4r?@}1#* zF3s`YAc<+c6NV^yhk+FAjN5czOVMI9fH)ya4nQ$`WdbeaD3=1lG@{6b1Y8)&6+}d9 zWOSNHfiZ$7rX%E0v!0|h0d-`bQO3G-`S;L{H-8~$$N$zz1?xNi4&3oW^&hM?3R|~e zt+2e9K?RO1c>#1}+1F;ot>ijxC1;qGAYa7daI`yvU@@a05whS(EP}?!my^UsMpp{V z-Uaf-!|LHXyn$Zo(ZizSuhNd-u;ph6Pg84~@H^2L4sm$($m*#hyD8SJH~LCPUxc-7 z2C71mNiT^y190fHr86Pl1ySBESx?Y_zgs%aRIp@JQwZBzcnX>7af77g!P(NGV4Bo> zgCuXPo408bdJgXsdd^4BoN5%RU!tc>BZh((f?@#O6Lf#-b6m50^V+4%xDDOvLN3EA~M*yXx1S|Rk7Oi1{pAQmZc~cIWbY!#KGwkRK^H0`n)t}p3l`SU9W}?WYy*zP}Mb6!RNZw#+|wH_ObT0#fLBa>#bPj?4ieQJYB7Z9=>|@ z5hm~4eq(vC$K_MU-hJ=LYnNztkOl~`5VI@cYmMtp`3Y;CL@_cZy%U)`EG8C3J76XT zU??`zi3lk#fwdAVAVi5Kx(GM=hn1kTR6-^|WDF3fNUp{3=`S57CM~JSIZ*%P{`2o8 z)FfRzf8a?q^p_m=^8EkpW}m5n6KAAx!L6^qgx~#p{&>r{eTuw{K)qLWhs+`%NiS>qA%77am!3ojnfxYM!&|r=E%19p8v_!Bw1|^85E*NRy|`CtGow8-MwXLOlk8G<%UFA6^X6WQ z%LTX{mxHwCo|Vlk4Mt+F2jLcphLwcwRjUdrfoW2M!rB5c8nb+6&FzjTqmu(&n-7jbuv6z{yfl9ZHLAM?xAb+_p4Z znprR-NXD#T65>{l-aEK>fHKi&E=2GkIk?9iiU#TqK^y$84M!z(a^MMyy^bU`ifcdq zO?`vSQ*V4fZAbs=(C6E?jodlpx#wU0>pdf$+J%7dcaEqZ6&PBmt1n#jXM{e}wYmE1 zirPKFWqIivwr$(}#M)&G2pQUhnb_b#b|L4~VV9XA17g@{WHx}4z^lU}N;R&7!KJl9 zr6i8`(n$o~i%t|hhf1^6&b8M^xeZEI_Sd!Ql-7l+XEe*WSMCrx`pwX z8LQ5oD7oj%PtDaIm8zAC4*}}=O7++|ebW8YhOghfb4t68@y#y3dha`@u6=~-q`}YV zf!DtgN}2|dW-*$eC?NK>GdYZ-vSj$UG{W;EG@@v9Nh6Fj5cprCzC=PvtLuYXnfPU2 zT{bw83paD0(oCO1N`lq?i3_!2oFeykJc!8ogS0VwXwrnfmAc32!Zf8m^^LC)3!x_Rh7 zunL^4yw4r!;}iUo@^`G3dk1e$9M93M_U@C+xL*$7PDj)Q?(~~MtE#|iGm z5we^GR28rGa{OS2;jd3upTBw>08R(Hec$OX>~Cx!%8WLP zGfyX92PPkg!DAe9r$8EV@WA`|cUDzAQPsBF*21o{R=xSg_J=MluYPD&cky_^!=EmC z_AfQ!PY0hEFt%eeSJL!hUDn^#Yi*mNj&Z4P9$4{irls`K?CtrMl}iRZdFQOD*l+Hg zhR01uniXalhyDHqbVWH#NhY)24UAZ`Rq^^V^9ahP`!PUk<8)?HlJGd3w{62vh%2{pYBT@2Qt%KavCe>V;kBFR1$`yz{Sr zLWS43O%~kt0q1hZCZx@1{bG&!!8*D36QK=Ptons^7YbS|>f4?A`Wxn9wri2$P7i_&YFjY&HnTOWLk++UwT=+eDk1M_oPA1kTZ{6 zzW?6P8ppTb-{0a)4Uo%0yTzpesJu!{Y_dMp7f@miF(^Hp;KYEP2|7E6-vooy&NL1- z#eKmk#Z`LZ-EJU5fnPT8Zwx^q{3I~rI@?@?EYV}e07aeiOJV*8w@*^manNN9OfePmcb;-dvFY_bBm8OzOg z-{+Kuoj4nxUfo%R*tZ*X27awRbX4cMIm!OzKkol#uX_C#^;`9Ahnm4YGO|<@ukeR1 zpZdtEY$h%M-Tee;E)%0mHc1(7H=sdN9Fo*LE5qp&5_NVj-~)SBrU@W*UYwYNJ^~^) zvi+KePf3MNPPJV%5H(G&)i@L{$_i2-Tn`=lE@1HVi($2{vr`%uEqqa-& z*~1@qH+BJjwYrtD&0FiYo&0dsLRO@nd1%FlCpR*A+Zy$^Z9(;)hsoY!Bu$MnK{QPb zo(qsO*A}&uhKP50CVz(OYQp4V?TLnL5q?LIK1g>2>5BobPe$_*G;NRcK~3AMfDsSc zpq4$O-7(4uu1|)opky;VgR2W4=|oa_d6R(hRT7 z2F%z5k7#!SI?fB&0k7AN7&jM68o4C978w_|?KQcA8^xn3k?1(kN*XsOk)a1Qvw$9q zc(n7Q+ZGKUKXJ(lbxDnSKsus!V=K;ma@ynF;C|qqB@fLEB~aZ9b=2Pvu6p?*W~t4A zR$&aE!yI84_cnzy4KM@PyyVYdhlr&ZI-TV7S`?=o7car*DWR~I2c`%pU@$|#;M1TT zHbirgPM9i_&B28$gtUW5RF^(O>iTc>=Vb9>D9gmmzwJ7+^WUh-w2RGS<=-9bwNELy z`Qrxldz4y1iLFPFczq{ZJ#^h5jG9N*AQDGMkvRDKR%_({51T}!{t?>9!M=)U=PP|0 zb}Am3=)HjRmyjU)A(B~v%p9B6r!qFy?Db;KUdaq(0kca^XoM{AXEAIjg+fRXBB12L za4($z6-BrL(L8B=n))5M<}r0`am9e;Q+kxY&|zUwZo3$;*7O4Hd1lK`vWJH=qkPEjkTus!%4N60=TGTvj`7UANtV@3B(ncim8FFzUJU)hetj@Z@*1tn*T}O< zNIf{ObA(+Qt$QNzBMG4O8~Rar;&1eX*j5NfU1-rEn86u!3Agx~Ne4xl47dZSE-h+G z13ZN4hbS(Nf>}UUQiD`Q<0gCwD*Hv>ibc&mpmwSef2aZ6>q4qjr6h)JuMK_*ZC_=) z4Qa^>4xZu?j41Rc>jhL~FnSSnU__lQbo;xya*YcPpi4T0+E#*BkX93=KY5`V!Zub& zqe5k$o&4#(;IBWt{QQB-=UL51?U%)+VCZm+L!(_8C*wIXSMe)R#95BSgHlFIX=r{+#HWTIX8m}$X4 zdr(0!Y@8$n94mcy1r57qZn;uoyo=I8Q~pF)*ihezDt ziNXHioa;_tgicfz_Uo)x$!0Pdm`!l%T@d+DvguZKE_r?u~pO}rLLpl^(% zFKDe0R`uqzQi)oHW?z~`m(>D$8;cr>v9YF%41eFs4A}&ZWBMI;ZKRiR!8lr>xd93? zYHNdl7LK8ie)j5>k1m|Mx@+0=gR?8f*HvAumq$N&DAo{n zX!W^k{kONu->~x0$5*X=WXePNeedme+iMv4S)AfQSVKE}EwMIHwCjvURB>=1OvYjb zf3drCuulMysvxZ5L_}I`Q{9v~ilA;f!YHPecJ^tTL27e+htn85dmJED7q1?cPosod z`k7Dac-9~9kDtne;ZsS`X1IwpEFwCUpv!9*kx9rY^`d&aj4J7}YzEPZdKoZbjVlpF z_K_b+zIl8f~e`quSZ}o!2YsGsOE%d{Nr-#F<1Lo6hetx(HBWY0kM%Tgpz8W!V>DqO6GlIakM344 z4e{Nh7@b+jFO5S%K|umwQkd@w2F?OC#v2x|8?h3^ffB8OfoPn!c4yr|V!T^IUqv}D z=3j&Lcq6>aUbDf8q`V-!TND++VLd&%8D@cz&qHz@DGKGC9;(7t8>br#5P)U1Df z^7$(@i&l;K>%JOsL}BL3FNi%t=jYvra^7!g6ssrP6*JXUkQvPgWs~?lB1#4nr3#}^ zY05$a&4w=$?KZ}g^z(ijP$Le-f3?~r!Y>kjPodZ_ozap~*hX;*%r>hP2{ba$=~9j8 zidR$*`w+t%xRFw#9aWM8!s~|L(wwNO*sE6TT~oWOp|hKx(>fCOr`z3!KB=M|?keCU z%kZYjI$)IZ3;-jlC_o57jW(Q_i1dNQ{KLBnvMsz;O(10ypBnm2?S*pfH-7;toGbX> z;EVhIa`sbAINBI`@|+sKe8ppMAMvWSIupiX!m0Hko;gKARVX`ZE_mqfjKkqY9s+`x zy238VR&(|Wjo_l1!hBVWKx-Xw(=5YH!)w{c z#=t`5wM%kBq7MRu&u39A7=p#EK#*6OR(@{G%vdVNi3JKSA`9r$dkazoH#rsscCmI> z@7ixKvEp6oI<@Art%Gatf}-y+g!065UYO7e%ATw^pdSB3eN3HNygnwC1(;*gH3rOO z;SBOGD2s%ADv-LVzKGkZL)f#qApbFfTbRG%}W=u-_F=L4{pAB<~A-Hz|S{QA3Z{`1v!)VJKO z&P2xZ?OI`0zz~+JGY}R*fe`r!gP=f&^B6z;^>R7()vD2ajKyL`guG5N%Racw`c{&B zC;}y&z{o5js4QB*@plj>*hq4iG~;rjlT0d(K!LbGU3`XZ*|`P_>Sk+dK0ER5Dh}ietr-4?dxO0xrsdfOs zhimS8U$Eql{OX?dt5@qSolZ}A>)-0lufJ4*r;dW4-;}MKol-5XMk>zQ{EiuG+NTD7 zeXnA)dhv4F^a!No> zbSJ`^pO|R2Sm2$s*v%-qMMW#Z^bqDKjU*(EpTT^nNl7|lFDZl^)97b@TRCgNj1`No zeyAp~t8CMfs;%lp_%Zzc1qPB(PfNttpq@D6; zX^Bu$c?^+=>a=>D%wWpYN^V7N4bUf71f=e&t6E$q9S`=zXG9@OT`Et+Z~uqvjEY(I zi0lkk4$b%fEjyFcL9%liWM_He&XBlc$fKK(>a|Th^{aLDRCOuA*@>pZ>}zn5UQ*kC zsl}^FJ|O!E<>>1uz6P_C!QHPQvz1HEAZe!w6_$_~Vx@AKW~f3as*Cs~yGd`w!2Vov zZXz`ka=W;DGkfi@+LrzJikiGx_5Yn+M{PoOO70o@PIQO93!M|QL+|tN0{R5f={ zMX+q9k{467!V_q<2Mn<~7&TJ^sc>7`Q~jy%eWj*)O3vZAxcqR*T>h)Y=E-GTsHp&p-H1PaWk`g*_9)#HEaIsWfcU0W|$iu-A=mfjR z`_oyV$-axt(}`_6a@&=S+pfanvEWfIF`ICLk*2IiQBu*QnDm0dF6(I%we-ve=>sbi z(Rd1+Qtn|jQxslRE!A`yen6E?>=Sx0w`PyQMDIg7U4uo0pD}Of2 zy13TUUcI(ly;kU1cb56HcZ{4PUaUJVEo;9y)K@(EXusfGkZGUkjds`!n{_e_J_>^; zNHJM040vd{tTU2(QOetF*P-H(wz9b+BRqk)6ODv%X-iXj*${C;b#-V9)>bWKXX}ol zK7os8!QblrqP^~owdPT1C^!S@(O?wewg;>YEi%7yqFx1pwj^;FX&Ta|y&Zm|1 z(G0BasCtDHKbXtl=!fH->4ct~17tz4B7X_5xJ&#^LF_A2ba0gDB0R3KpM-aV(w}S9 zt<~xdX)>`o>G%`qiRaiL!$&8KK+DL&gblqXJo`>q8Iuu@lIb!g+GRP$qCgT*ND{CL z30@0QL+lnuBFeph`{}$&V|%(L_ebTnhUhYnK*`w1RBR(q3b+^99bO+qcEynni@Sn! zdUf{=^;71r-(JU(>n?;;#2D zsa?yqYSgWp!RG^g#h?gACd)>ye~ECzKmmhu75#;^uLh36&sRi+z)$Ha`(p3SF4gQ> z^(yID-BE2q{Pt9<^x)E(#)33|D?0i^2?;cMl_h%O2Q~7!chN8Oxt& zEDfVU*Cd0D9DEufxX#a*Q4esT@rysPOeDaKb%7zAfs05ZitE zA|xMH`pAmK>)}J0i*Lp*N zUjYXRGGgOh0eDkmy@gvSxQT*v74rOLBFculAlQ&+=X6*xeE;7}5HGSE`*z;FF}G;< z0O0+Y)GMCiwZ3M@kFBiT(RM|AntB;7wx3mA8xV2r1sES`ECWk(ey6dJQ`G|I%gc|L zQ5uPd|486ngknc4MN37aY;yHQZUB<2#Y|$IP`xQ0s7WzHU4dHv>H9Zr>ecFM7Vrem ze~hGt@7L_yzJATloof&i@U!|JGyjh+3bpX_IwZT_MDq8gcR&0P`-w<*2?ZV@VRBk` zg0gME&lgRyH^vH*5)BA+H5edR8|>!j#X++4t-4Bqrm6s0pWh@Na&n}8`6??}RQ1-2 z>_64&H|npPZ)Ee5z50Kq5i?>KXRGO9+AoDzO4ae#S!Jhdn2KqyClaa*ui@2cE25z zPvKoUa6uFp#vSpxea%uNHU_XE9fx>vDe7^HhP4F1icsD4UbJu_6w->48H*iBmz#> zZgEnMp&qh)gx~xLBj)!fMbRNdggkEzk|gnDoT?P*z%Liis{PdQs@nX;=h}tE$^q=# zh1Ql!R1ZqWLpRkH!dN)Oi5*;u z+3f}=iS+y^h1ui(>1E^YTRvdz+#>{~fb(l)+6tG>s^#iv)l^%{ZdPAso`*IA1E^#( z2FWGDo>WIZv|nS|*clJFHqH)K`76Ft#KkR~>flAkX`2I+1#IV@h!t1hk< z`&O%~s+E)`q10 z_B;=V#!4qlS%#KSDMS%SMnyh`EF;7%qJ;~wj@P5|5Z&6u!628AHqO4Urqb3ZY}|!t zJfUg6xzG(oin!k)n(^<0HKifn9O$pJ_}WEd&TnmD4m+T=kQVVcHf;euNyIGkHlm1j zS{sya-d;OdjL_sLc0M~MzBkpHsNJFssBHp)bl5?%Hb!G zI|bhxsx}1GJgL0?BKpt^iKVbu!&nXbxK0e$kAkX(uYB6NLjEO{2lq>Z=v&QOzG691 zRGf5@b%#|>FSrgf1tpd#?T2S=QccXvwiL*sPq%o-wp-9OT{`I<#wi_O#NgooubXIS$X~Oq7d3MZ18%59XC`6F7 zL~TV!;q|3uh?zxK(z`CmnHFmUa?#CEEO9&>_9Bg6Jj6d~7vf7TGUHOPV2~_mL93)j zAx1*kBOBlXQa7 zV>UZ&h@^EHZB{+L6cjio|B!|VR@|soAs=3&F=CYTSM*yOZA@gmkwN1HfIf~!dSb~3VGJ8OMBzdo2y@vVhX1|D|q|d;!!&%F4 z;r(&e^6r^aC*3z|@|1hUZ|6Puz=FApm(c!gs{c&cFZ={gAsjf6!kn;NgBc1=nX)DI zR4L6^0*`_bw@qvqDWIn?ytK98P)w}>77&;1PfyS85YyGRqUliR$Kj&BB{U8eL>J>6~j{IJD$ib2=c$pj;Z#tPla3?@foW(ilCd z(OZq{6E%AI+rc9b9U3{9eYbP#`e#_XO?$*i!S~lm+2W4DBZpU34yU(vJ+O8QgRd^k>I*$m7C`%}!1hPjY1gB$ch`1^^ZK z5Ie89cK?;CA1^;^x5i@ zLb4Ewc`6eu>14fV;3ULFD6|gPzEl>5g6xnWdX%+M|51J5faDCV7rTc}u;q)P>zEeH z*&9P&ZNy06d69dgK2*AJPid*u=yawg$D8djqCGw_1+_af9f?Va<(1YXOG+RGm16_; zfIrYV&_5uP29p%<2|iC*rSJE3WNDC59Y)h+!eb3H6AU*}FFgh$Ihz8Hu(0N_=g&^1D5ovT6}zQ_2K|8GTZv+H2i*^s?18l z7DSU$MJ=xoKnB$4(xTMF#H0+L!-JCUqRZ$rC+V_VCZzVObhyhar3ACXW^ooS0Pui%fNe3<6gTPNg4ef06=CRr%gJ#?0g~^XS&dv|$@%M|1)n2y^ zk~V(!bqMuHE{48ey=yf`eCQnZmSzYuOFJj|klz)LdJ+2gW=`1@@6%;AHzPWyywVVh zStXTMipln5e{yaz6wuh@*kpHVs!&#$s(0H^3^+W`D2@H;_C>fHOQ9rWeGCEKMWdDl z3Hz2=ScLym1SM!lN>ESsXKLsdQDo=UF6n1$wr*bY+;{4gR@IwCantTh*6h18dwNwP zgLB&A;?kVOhhFQtp$h}f|Kb)c2P}rmy4jfJLvXTJ*581a{3LeP4j*B*(4(|jdO}JI zhslEscvA~8LDw=TEm`N%$9k=qu~vK$U!rpp=GnM`@fD>*ng_^`vt`buIoyE)gCqG> z(y@{B0%nkw8l&YkDt^v?*`j^xme)MHZe@)cbMU}{gQ2&o51)8$;?Tgr0iS+6b{IUY z#7*ipJ$>ZZw(UocZ~gxJZ!Z6J=iV36?)HEGO<;UFWG47JrLDM=5^*0P5<4wE-fm3t zN?xNyPR~fQTjNZM#VuMyi_Y%`)1_LZ+9VpVLiruUVZ#vTOk`K6L!5X~q~3w32l2Tv z5d^z86Bq7x-D%kT#D*QCN0;Bbp=x&3+kY9fe^IwiOqlV0^}!eS{ha2V8I!?&di?2~ zj~`Rt>8oCwxIoT+b;wk;-!iZW9RZ{|g^($x=kDaNLz#{dJV*2&U7AfJ>1bC12(@aAr`Z^8 zr15Pj6$WDDH(m;r85|p56>AK(O=588+U2|GTTR84*uVeq5rc+^Kmt`iof^d9scZk= z$E9AuBhMUtX~#1!zO?P$IkRWYy62uyN>vs1C0)FxEX6$akQDltqK=^*ai30)2R=I; zla#o4pBLFqPJ}g5;1H%>%iz)0n8A#T#v z@HE}b*2o*8MoWy9033_*m^o+dvLwLOj67CYzN(l%dJih6tl)?Ho^ zF+=Z%NlWnPrK}d_)LxY~*=&xLV_|uZMTAP@G$0xelnv46fn=Tk-meC>Q}J z7Js-{J~S3uXr8ek7e1?g`+V(7kNs!km^In5`bDQFTjxI2_uUUeyY8&M-y8SPfbo0A zkC&>|n`+@#XI|OI3U-d{H;k=s8F<>4u6|qh`jbrBFlOo_Hy@hwFlLd70}Q+mNNyIP zd8yl|m}Et^A)1*f2!uxwLC~)zT7YCV*Gpb&ijji=fg>J(myw;XW*6#?i-C^K)u4Dm zRl84A%5NT+AS10isEWV6MKa+T)u9B?kLKA!;1mkm!P8FhzDRhy)w9RAT_oU?=LUl{ z@=(>Gx8C?!Uwva3S}Ic=@+WAC;?3gqsJkN=M3WAO7!jKqECvQn2|&NIN|R=&(lGkIFgqTtzBJ|{FX&G7wYAXrns{JqWMwd#&5|Mg!DLz+$t9$ic@EF+nZA&EZ9C+3g`Td zxgr4DC9Swe|oSEK*bYXR`{PBW+(>4Tf%IQ%Xcw!b&^{}3%o2uNtT8E zTjq5-u;-b+B^}!z)_EMuyg%Q(df+8@mG@`G&n6Qu8_TNTEA)ex<&sp|+@2uWrM%Xe z$;q(;Dx>mCa*NUy%?4B^v?#Sh#l;&szb;oto8m%!*a4`Bi(=|2E-2r*BTr`w@v)9` z+>POgJstnATV7~H_q1?4l@|G;TG||rEK&-kKY5)EXuGI*>bh?C483i5PT@ms$8YX7 zV`!h@dBqPEPTtVtzCk_i%qv=4Fm6kaIsGec7lqQ|4bv0T194r8H%?1RPmW_7x)-jW zmXewj-?eDN^b|ld(Mg&pRLfbY3how=hodlu*=#h~5P!!Ez?gyydqAbhVAlc3T!-*g zaX_UDa4xw8r@23q#O~J{D+gT2f$fRH-`qZuut{u_G7*IS4XaqB=7{d9h0~Z%ty#=I z2z|9=Av?K@IhHYh@fXX~>&w(@Mc~O=_3BHo>mkhqoErp->ea>F&&B($6ejED@O5BRzs^@k60&6Qq<6cv5FKfR7Mz6^A&mjQ5Q z6@VoNUxm#iKcpuTz6E;P`9|3rVx0jc|uUkO^tUk$q=Lk8b6Ckdqr%<+=S1IaudVPoOo_zdk3< z#t9?jum8LLwL8E-SO|mbl0G= z_;y~WIR^V{!}>ZcPRLAdzhu+uh&SHfNU|syN^l!$c9H{wMvWRWWYnlZa2TB4zKxY^ z-!2P#tM@!tvwP1zwdmVV*lYhmPaf1wKct+12iil~5grBJUI|QGRKSgxq8RNSzen_V zB%9tZrQn9+Qcoj;4OlAvBe4uHK0y7&AA!O)MK(#V7Y{95txji~mM>I)g65r^Y~Cw* z-g;|1u90)69_?qz%*k>73K}XAi^OG04Lm~Gr7;dE5h=m(lI%}*!_uA*n{350hJ$A! zY>{`Ux!%E6C@xj=HG{ikx^XP^ZCUTt2WqPOF3)PWqV1j2r%fm>^OpqJ59$(6Cwbzk z1uLHN`NI4r9TUH>5YNoQy6?ie`-C*AjG5pHz?O;F$@FH)2qr?hk_b5D z*qDGpqDtA?TA<1yHY2RXf;3TkJl{twI~+EtMU!PHkrCor$+~>GZ(f_hD>s-7Ni%O> zxUPET=I2@Wfp-lZa{E1#rBh6)x8Lj9T%BFA?!hN_zkAonyZR3wR#N!@ows7_7ujNT zxHVwIC4YzBAWF#s-<$A2FbXo1$FN+^%luP6)rDU;sAmfsN}9?0J06(|vC5TfD8XV#u(HkpmNZ_pI&Sulv9i z<;oj#CO%x&cl*p`58c<}zE-V9cAxNIXhMfReL8gRpJ+<0U_W#y&g~UwJEph;b}J1t z*$N4lYMp_0s=2Iu9CWXNYqyRXZV&HEnPbU-~i@Xp)ssF-y(oO3_b+u=y1SxY;mAxPSZr!6exjj7XF=n7KDEnPVQa zhbA&dpVeEpu3q!hmbI_Fc6v;=!FgSAb9OHrSjonwLMHlbOLlr+^`>cpVF+8J-h1a= zBt2KCC-pVB8zq5ojarq)F|#in9(WW?%Wl~`*<(vhw%L+XB@uUduD03OQ@)3Jt&NgG zN1f-c6QA?ZX`zLM-W3x)`*=rErP^RcaESCx%Px2Kd1+7oI3#$7w688Vzf0br2ZvT|Y1iW5fcCkC{n~cFr*Db+UFY6?I+gZ8Eg+H) z#5>5Z9j@F{rtX6j0?&06Ej{c7gl7>_2zZ1Emc1)L%*jF4@PyLh1ijDPCcTy4pDpHy z>1Mr4SJcj9>s2WPS_OJlX1B7p^0z|G7f&lsE2Vk!yq=ZKnUd6iA@X~x9$ty?evOjB z5(%+^5;lr>{1e?t+WP3hP73gPW=1p3C?>cIV$w4Zu7EdWd5EljioDFZ4tukdxVHAd z;5&zov^&0HbLA`QnH`7szQcqTtJF6Vk1QBDhPkEkR$bJmalH;LUNGO6n`Sr8$s9Q{ zZOJ3;&x`kTZYfSWvE<2T)N|?wix*#H!kztAqRtIggi!uYf%i8r^&sKV@Z6n&ZZXWM%UNYo?@%~yh?YMXjCcvVp zt?gC1b~}UL-X8i)%$2HW4_vSo%!O3v;kaX&NT&+~k~6I)YqF#R?wA|sJcbxEz#AzD zsab*m8-N3BGXhOO@;E3D#;(YyH0HvsEro3$kP~!^b_Hdo>0pEib8S@c3bXG_G3)pn zRqAI?C?DLM{pPVxx*NKy=R0?uI(y{QT~kKRo;Jht<@M`K4}h0o-SsaIAC}&JL{;zJ zzjxKb6DQ`c+4sEq16fqgKo*#(pAG4~HLhav+iyknJ5XP=njvBlbZ3b^$+E)%35ksp&4^9RJ^e9x%}Epj-9+GT)7v2b zpP++cJh)lefu4zf%bJ^4uKwq{dH!_&$f9m?)r<2z<+a6gp6S>-tI*?i#3uqf1#1GG zLw6B6N2bt6#L7l>k1}OiL?_Xm`h)lT)B6}LvL$unxQ91D@_|=pcRCYccrxqc)HDxD z)ENCpk4KRjfUHImj412`&Y{Mq8gt>vMO0Bf#n(wJEPz1|q3j&BhnGhcl@mxxejSKm zJJ}f4jrDjTzkR}CThfw=qw8h^WA)en{>1CaQ+iRjHq8f?ZWAVXpL#wMh?eR<)whvy zlFc%aHFJSRj;JstPQD(IY<$SIabY!LEP7zL#8@PgDFtW5^z zX&8EA(=RWOyY}-3P#yQuvV!*UhwT1&6M6;zw*C3PYA{_wdoU&`K=d z*UTT1_6K_&Ieqd3qS`Sc;Cv_>KqhViD|nsU0(8mI@aVeZU)cXJ9uLG3+A40zmnHmHt#@+@SKkE*kDs~|<dXVS{Os&3-8d84 zE>U-=V*NsrQD4*v0w5zOd?0L$<6;y=I;UoYN=jNZZ{NOoi;|y;+qNw(Dk`G03f>4@ z6hdBU&N*MV`VSe8o3chCjm|sK2>v*nbw~5&Ze5(*GTog{ z*^fwW4kI67)p8prz|qEI5yMwEg;ZkVe8VY-*u~vhSXhz&&NB>PeFiH~c6S(+)8oMn zpEIUjtDjms*f3z&^V0Qn2HU2ErtNIoBiU-Ts8MUYkbx&F&<+HhVhwCVMJqdR>E^n(%0j^8} zBzhOp-@QP_!)Todgk8Yh$bumr24@3OjYPo?G!mfS@Ph{p0?y#3 z&UnrJ1APF2dfX8Y$w@=Ah{9O-Sm#={OC5Da%v1jdJd26yN%qbAue^Btqr>t|6#e*O z9R#Xz?|dXr2xc#P^6~k^S!tYG6-2in;ug85um-yAW-n|NW-Fp@C94g%NHSt?fh6D% zY<4pOqa!(nU=K(>Z4@sM86uAuhy=cqzny~Lwb1*$Y^b^yc|b2B9U$<{H`SC`ShZE| zy+VCWJ%?m~6DzI+&uL+tu>6C51Mp_1AkGvOk=!0#Y?4KZg(?zAO+cn@f~<4-khd%O zd>)9|uEqd75ZN?@;>K_U8WG=u!y{321D4b!q?1=RLs|8i8uW{Q4|PN#vHxv(b<@Ap zlj!`Hzo(=2?dr8~VbyZ+FMJ zW2bwV=?0INFZkwH3VPmMv+~4?-t@I(d&574{5*uQ*`_oB_7#g{MPQhl0crs}#DJQ( z2FWaOPb?2cBM((HhyLL*q&pmxcz zrD9EJ2z`^MTk3rN$#G+M6OF=(AyZZejR08Siq2%wSyA~C0W>H$02DN2z?zU$Ci1MZ zKO6#T%kWX)*h|QO0P7O>vJ186XKtKzu9jU0Fne~pRAVA#f3UAqAAKWxAZP01lSj}9 zz|Hl*VTa{B9=7vzo5^GrB^PMUpf~Fi5|QRcwC9Pn*lcEpMRMyUGx?<{0Tgryi&$7@ z=dxg!nMPJ6On%zxh*%w+vUJs!wd!ZbS*m&`i0&%WZ5Jn;2u)y}<|JC&X#^`2`6ikZ zr(?Bxv%(>{-6mqJxD|9Btd<)m8kwO0?zSm97N?6vrh`5{!5~`*IW9KFo$KuE6rG6R zvm;?uC)&U!X~cALU=#YIAvdfdxDY=yZXa%aeL(KX-mZCP=BDWvYA*mKwwjH4ZKA=H zQi;+kw4zAbi+p2M3)s0?sdrwYbw!-EvLEZ}hs6ppODW9m2qY&bIYg${HA_oo0lz;0 zVab&Q=9nrbCB^zBhar|PEkEFVkWD1i@Z!cWKy$j&Bw(2Gb*B7mDa{R>TUMw97ywy^ z&Dk<8f9d{ZY2C+HCe*|azpG11)v?EN?^-`c9WT8cGBKdPFIAno-phBR6zrK9qccKX z#g{YhoPkjD*Pec&kDmRobhBDavw*2op%qVo6|20o1&GO!>W}p&(=_zy&HOAiB?U;* zPMa$k*&1mgJWeTg%!4m@!#psVMxu7ZM5I5MhosFzUas!HV@996r)rm`wy!8NZ8rBC z)Go8CW=U-8KGW|||0<<~4xt=O?@8(oed_^}AZ`!1qgP_+SJ4z-I!fKo26UX%Ki|Mc zPgeaUU|`8-R!Muy41c>jh!$or|mo4mpx#L z^y=bL>~zbG+3D!m*Dw-)Xhj96gC`!`fGZat@#a_hpC~A{4cvc)4tF>}P)5F7L2+0rPoDNgs)n z6n$CtpJOIVm)qm{=4X>GTD*AJ{lmv@8FJ~Rm;Pqgi7(!G+HQ3GIn8-)?u6}oYpKyPLFO+RDbJjIzG* z6@GtiypiPVA8f2IiyuB>NdJMF8|Jj+f!zmI4n(sK>|cyEY5{C$N!7vXAe;>sR96=i z8@c`a_k+2ozdtuWrRVTTDbd-Vq~M$nBt4X)mHqFaRk1A#w&>KXIQr=9vq%%+-oCU` zl4JY{h2(F=1+lhLWL7#9~<@E$uY4{#|vi%(BW^y{=t*?7P2zJoSp+qb5zb z_Sefw(#D5=bHkK79^AWAHEnwE?nUqcFmm0*y6b*EW!BPBYbW01Zc3hSp4~s^mdkMU zfB3<>w;Os!kDgWKZg4xs!UF-OnAG_4FxtC~KYY+PXV%Ywm@6 z2d3NxBc6QG)!-VZrDGMJtTK`_6ERID`rRrShFL^UiG42*YqkK^Y$?%iiRc|KOdFh$v2b8?K_O!&U1Si-$y)UYOOiAKcXQFL;I8_}X2MY4lItth%!MZ5;k zWyIlF$UPoTGvCM3cn_>>J<%0IPo4bm#2-$+|NB3D?3(w)znW5g@#lW_gk3)L`I|?N z3=NugbwL9JcZ)rbf;$s#>gVIX5DJ?1wlY;|zdf++)*~}}p3+yI%6(?DwJKrOq)lj# zg?6fMDdd=*WFfp$To|dCN0*&m?eTkhLApzE6SzmJS)Ay#^7D-x9O%gLW|;1>9)N~glo`VPXbf3Eb|3(YEZ7=LO zZ(f zZS0YmkQ`T@U6f`Z0GE-Q9hZPj;?kn>3MBh;yJg40W{*=t)DHezEx95^G#csD z;u07p;a^zhy7Y|nfcR+Oya%(DzsPw5&H#>l^hR7`zuJblL!W>2mal(pzs9(OpR|r$ zwkDyz&#cUwuCrSc8>;)%C#+ef7kz1eSk$*ydA~wc{P~wEx3FK2^4eni{g0n~yL*rP zk=@_^wYso>kKEjz-C<=V%X*jl>M-br!kg@QjTM7K-OI~W@vu>2N7N^T%=0Fs={N=M zPZ-xYBAnkCZaiyJY1oyMUIT|z6*V2KM^fWV|L?lI|IXo{tiwABI6UGrOkNs}M~D>- zf%1gD!DA@tbP=ih$huKEkghb`GC_9yHm&2AYz>X&ovR{K+>KHIotSoyU2yB~R5 zzy5y~cQ5QdrQcxhYfB2t3u~(VIkV;#_ALBv_n-l_BUF>>C8nnG?!OpE~=-wK`8-Gwv7N%Mnf;VrTF4%-%|yeZcCHbJmau|9jxW0egxAv?gszV|9u*r?j+Z ze&f)@k%Rhr&9lb_!*ILZcl02$u{$i-xPcD;@4BnV^mj>f$^B;W0?z?LzM#DYiq!}2 zzk^+6#;2r>7UntJ@`n^THn@l#02hFR(zNuJmd{)NY-J3K{QmO>t6p;#4xdz8x~TtiZ~prn|M+!_FDbul*~0nZ1=p-> zvcLIyQMbZwXvx%p1Hnc~xT#Z`n{{jT?|x@b8{4B;ZT;Qvs&CE81>yV|GvyyVk1Q_i zQ8?4;K4V@{dC|#-`j05>mugvA+2Si+7f)W^<+%Nps5RnbcunuZ+P?iWGE|^%Swf+A z;Gm>lCB4p?)GZXsD{;rgB{s$-k4VJAyD_!IRac!?eb%Hdc^zc3%Ll>W;d0rDheUQX zP(*ZrG}wm=BLD9bwRA!vDTQL%{(%@mPwi;xymf4DaCcQ+)$^5kV~xS}Q+o}&?!M1X z+n?BNSM3-b*R*54BX^%~__<^Fe0%S}8>(Ao-ue7Hk9b|#J7(dZ9ocqy%m#X^eR1#J zRh4Rsx>Cd}W&?$o6&E{3(2?LSF@mD4@QlS>zs(aP*!ER&Kj*=GIO-ssr2?e{) zu$#KKMJw4_bb-A=45;%SD>z5p{9^`GXa$&E;dA?ta4tNKCdZj+Ce9jVrNHo)f}?k0 zur|f{jkE0NFooumJAxsxI-%2Q0>B@zCX@p6o*@w=GBrfCNk*)KxOBt7dHw8&2LhNz zp|?aALG2g6WjIPXVkS9f>s1P+Uv1m1I5~0lw%%2@&wlc;#~$l5wzfGH?)L&JRh8#w z+*W<~ zf9Lw#c+Y(t`Qs$C7m*d5(ycylCnV|C}IDPn`>$rZ{(}xjp5mhDu;d7IrXk(WsGBu&hG8v_% z%6bVaCH3Lpep5hYi@tX6>Nj+Bc9uVo+P8FMBl7wfc^!%7h11EVj=U1|PI-0WQvFDj z72UfYY8+YGH#OkT${sxwhW|30I(f-`Csqe?7XY5NaRc%KtcI>{JnMqeA(Qj_Cv@?q zj_Z5H=-#vZbLVN^@Q4uu&mKCY|L6%9Up!^b%nK%8(XD6CqUy^0Qlqaw!+ZAVIagHo z&A{=KE9Q(o+v|%?-@O#RQ_B{AvJnNw7HukwMp176 zuv?Y&?4A?s6PM^8&{$XQt>~MT*43&kNiM8Tf*D=T`o{*XTei~+`i2bbSIQlIg&7nd#1Qh=a1q~5*XuPnI%DUZvMLmS48F)+HaE0QnVTBjB=xd)Hw*TVRFZH1>*AENstC2Yg{)%yZ zcN(m``Pc!eOf(a`I3kgPcypXtz-t(@~6e+=Om}8w5))* zGmO-N-tf;nFv=QWJ6#+bMvIUA65JB(P<%Dogr~zNR_s`Izpw4_!|E$JG47pw)vOt& zoERU`Hs|J>jpo+j;?+yvvUzsvWY>s0*KM0Qe)5GlMh<4e`da+w%O2mD#xiFwGEIta zVUN#;(;l(?NXRnI^l~c_t|+2SFW2g*g0?SJQCzk?&J^JsB0RM?n~~5IsB0EfZfsE# z?3Nexk#HLIH+$YjHRPmPy6eDkSL^QG8)P5y?cd8jq{_PSdXW|J*fJXXr4mC1I{_{& zHPxSx0apVFN!TxSVXw?cN|u9Zh!y05CmcA%fzMOuFf#pfzx2mT= zL6z7iRO5%oKRRjWi6Q-~6-DmtVei`O61icO@)8 zQ2W667qjK+?(w$2o41X7V#HIpzALgyABNCb%CL&7>KYGMo4%4jAT2$$C?mhHz-RU- zFUrr#O-4u_xK?weVpW~&hfB3=4aaDr>I^o5WM%P#LQB89A)ijDu4*S>9~5QQ!@#6L zO($9l{qf75tWQX2UY+G@eDsPx{LixsXRI84#r6&Q#+J&mC399>vLW^Cad+q24W60} zlgHxZ&p+(P@7y%@@l4~>-G_?)^jgB^u`RRya~$haMLG7N2NLDKF#ejT}f~! z8IMT7aES)zUAP#Qh~OSk+0E<}r`8#6&MkIP53w`t^0i&2w%Ze1Hf}^PYg^yYwn$&I zL6=+X@b_SdZzg^Z-Ynzc0s!MaDcK!o#tomOo2EA*0nTj`;8Xj*eUF#sBcIDN1|ba8 zWV^X}^Je`Q#`E^}<#x9Ee7X8eYIwlbT<@WV*&1S1#o;PwR#K7|MbfIq^__ z(P7bW7aeNZSqpYHy5(@949 zIs8(tOK1aI+}GA>;v~j?Y|KBBmUC~Fvi~U-P4R_f8sDQ;SVmt~YEn{ivL48Cbgvl z?Syf4%CEei*=GIv0SAwN_?Bg3XX|$R*#ubfPsnmoN~dGa`3^0ZCQRqCEF+MZkN|HB zno9E`6kb{&#m@j2$toEllN?CQk43p~iU?lAKUix=G(&1i7^v8vMVWzMYDkU(oDuLs z{bA?UX+IkBV!L>UkA=NJDP8tzPj|Fons6P$NT(&m`QWNPDUf2Jlxc{&rUwG?hL)0? zWZ@*JoVkdj$44<5V$~*gL;2^7GX9`^om>mge`)Kq&d!BLIL?Lb$(%WQwH?#t|9$9S z7&gC=_8^JQ0bgxTVtMH`maB=h&JVE%iRWQF$FSscAO0=UyV6~bwikcZv7;YvUzqxy1|Bq>ZI>L;e;06p=_y} zwn_LM15;0^RLy_Q9->aXW-nW|ZIgTQ?%m7VzBoUWIkLA}W%p{kRd>y?XS&`)IsMpc zS&4Q_#JQGi%qQ?G=RuSTOff!P^Tr1ZtgdlF42>oHF8c-10y$#^$1vK~1;U30&5f|9zHhU|S(ZA?v@K=6FhKcb!z9*~z6$Kd%X)F|0NW?8IFoPCn_$?=_ zfjjBPnZXG&B3elFe^GkiEpHs!!o8O6Ter5f+AS@H?nE{!#M?NWpW|L30_nod7Pi%?Ou(vT_zY)zB%*zH zo-;`qay&x*FAb3AnP)$-qfJ8tXsXrS_4`jdGywU*?f5&z-lKxAM%@Ruf;hqjr}fE7 z+{s4kkE82p^vN9Qc?et7Lu;qXJ5?9G!YPDQTzA_KwY%wFi@i{%+S2=)uPbWZm8T2c zm?%_6VqyT^*1C1~V^hqZW8w@X`o!bGsR9qeVv#ASb)x2w`t~)4w6_ych@XzBH4&|b zdk2Uu)HbBW57Y&PbN8uTyaIZFLTJ@nyQX?B^hs})Yo?UE!| z%>RTfhWDV|FFU=%{V{eOOSKy8MfJ?KDhtZ6Y%|hx3oMxMi+hfoln^W~MpQy9>{79B zi{{1ErP!HsKW?eBRmG_-RwW%e7hQ|JD6E<#LZR#?(B_>-XEnLb*MMnvv0 z_I2;N<*GrGn;QC^|J2A&=?m@sAkub+PDiCI&p&6;}d z%!PXM)ApeW-O}&Nno)>_%>=br-BNI8PTOWI3*R(nshlm}!u#;QZ2QSK4m`2eK5sC# zY-JDbHPCTpIMSVQCZolX52QHgdGk8!{iTeArhx+u~Johil+AbbbdaJz+4rY6& z-;#3lPj9{*XWaequU^{oR5Uab+3icy>1oV3ujIo z-D@RvFTcG~B3WTCI@p-)iHGhL7q8&hLLwf<2jcRf4ym&y$+XMOIdV(;t}`zaI%K9k zw5wbr?W(O?ceuOWci*XHPGlp@8}@1gVaM?WoC59e1t)LpSvkg!$dcUoN=&vOSslLt zXN1OVdo$<~Cw|wq9uxgjYK?zz9}DL|w0hP`!%9}iHxsq8Mw}E#Q1C^V?1QgCaRaQU z!A~e+MQ~P(s>1k?=nOpC9ZEr9jq%O)xE)`eo8rqG_T>(H92Q?+xJI|#|G`DKJgr}H zYNw3*$X78Nha0=OeDE%=d*b4gVVUyAC&bG+ZMf@+Q_0X?@jcg zQOg@@hIMauKcG&BNCmiVRzW=7XM<-^{U_~XV zR<7!;SZ^${=kHX1wCkQ%m#Mi=+jWlmzOrqZ-m33z+k>m`qw)0;L<$I@pOZDjIyU3t zaMmPIQxZ-u8FP}B=t6jAxD!uEGxJ>v^Ak>~$_#;XQPCY2^t{TUa!(K#N%7rm-aN#<|Uee)F0!=vz_&CY|Mv2HW6)rQ_fzjU6K$c z%m@E4J_8#EI9L>kZs|z)8FC(5z+hs=1zaFB6uV{Xsh#!&SEXH~e-jD0#-W99mmF8_ zd*NFc)oMh%7MvRJ;Y*0z4*i73@3Dl^<8@~Z=!8dU|8#7CMf8HGPQuR{OAwl8So5al z*2VS<##n@&c-M$H|2KB8m0Bb4rW^6`V6(1k?2akT(35eECIQ=Q0oY@42{Jv=IAg&k z;@@%3h^^RuECSp^4|R$G=XCy=f#6V%P3Zr9=>K#nhf0g{BtiO<(%|ynzy=!zy*E8M z2|los(h{PYS?6*%LogQA!BNYcT_`IO*#TtJIkp27G!cOI_zo>#ABldKj{641ZaqFN z&6l2NS$==Ij*_Hek_DIg(tU{Zh)qB%kOcJ{qUh|coZ*d-W&?IgZX|v=1}yiB5pe>l z05$>pw5;B^?52lz?AX3ynXah?5*u&PHEN38l31@FK}@TO11+xcHlbW{!zDw?rP4h( zfN9~>J-n}`qo)vL8}=3iB{p0xKtfywyl#`HBG;5fS~|!Hnu_JJQZqUh3A<^S_4=T- zUSG6eRde(8*DOlkf=~$d{M{aq*U8LDPBe`3yL|WOmi3H>A*)}BI0;`kjTtye9)RQq za3~*37Civ(lYxM&To3^hd?_O1Y!AxEVY8RZ3Xur5uo+qf2U?W&3Zn&HwtIaGw6twg zUU;%?w_dgQn*3lJ?sYnAU9rdUds;x^`v!ceDM?t^$0sHE;2K2&Lh$_m8Q;sZc*+qZ ziB5p}g)bW$PfXl|CGG{guY7o~y6vT^kv1ZU*hxeCZ@*NgtF+AO=7myKi0GPnc0zV4uA`(R;IMi^$MA9DkdBlcYk#)Bv_K6u zCUE_^I>gv)mJ=CT?rVtFW#D3HK71PciyN}Km+|RgSo9!|he}x}mrt_}A{`n@YODTlVN{^aA^z z|50(LM3<_@E%1}B$yoaq%k3o7hk;(0mev)c-Ca_e4j0QfqnhANfVW!R{jaRsQs=-V^Zm0& z{??Y@+3~AO9-Kb$fh{-PlcYDSO;z1mT_=YIE9+(z9Q?@s_a~R`-QU~6eEnM4;#t_;5C=l z1>p{HI3%VC$2tnD>{wq##;{bYP`aeOUT5|hsaZrJm~!s8!Opkxp~FtvpjSf0_NuB!%HVSt|-!R za^=A3xR_4XvEw?|)agAqA-<5`#$#w zb|Eyr@eoJc_kqUOllm=eFrMeV7s9p(%NFi;_f>x9PI(}DD-uR%_lJz?^_KI7wham# z?vw|j9@??ybZ3E=aMdDDg3$`8M&J)f`9W%NYn*{MV)hZDv5gAt^PExJI7R?z8 zPN)^|QW&vBhMeV)V@3}K5T;O{wiY*Z^fiauR&`Nl!;ci~(BrNfcI~~-y>9a- z;@+ZvI1J@(O~No4Q9a=&%Y)*ujlfWdu=b&BuQuCH=S;izns82f&Vn`h`igb3E-`l5 z_u4aFG?#nS3H2{2g~%785W{*e(a5p?k%C}68p3~Jg8_42Ab?0MMlwQ|U{5Ni-Hg^r zZIW5A$T?ibJ(-w22L>(skM^l?*N$1bTCI&3wl>%=+uKvRZKzWJ)(f1gEIQ+@L4Kw~ ze$rsED3M4Ua2=Wg2d^lJ1mTDUOi5rUj!yeAqCeppK}S`NYC&{IroBKgRp`fVoH}pj zvTNEl;Rec#?MG}gyuM-o5w*t&vV+KMxMOI4%C=eQK906&xAsNE=Ksywhpi22DN*6! z5Tvzl*PX9!{_placYxY7tc_ytgR4jrK4s0Qz3;yn`q~>K`h6t|d}L={j5oCMQB=gv z$FL(#G%Xsuuq3BWO)WA*qyy@-kp_FG24;>b)e1_rk*}iBjlnn^((NC2s*d3-13IF_ zc8aUKb!*4S$_)Dc@(-dbi%u=E(bAx`cHXgt6{qO%SJtk*6B&sKTIydHG-^NXWNk#E+ zi!*?ze#vlhC3fLt$1u#39MV=|n2sJibi|cW6dl3?WB(wMqDW4sXo_XM7){ZUp)(>X z_L}=6^CPA@9QB(9`%fW?j`>lmrPlz2IV{%7``{Ohe=GB&cwvV(irGyj@mSvufT6bqVET?eshwIGVxmKS%T{D7#P#)HG_kQ}x!nbdN zH-UL}vwf&-hpW=E|FiGy|M**1zv1pPdUJ8Ey}-WT-fAz<|1u1RN0Ux9sli7SI56!key!8+LTla68r$2JRq^%oQZA@s}cbjX9{SI#Ve`g<1 z2_Ikj#&daPca`S1W^mB5-NR?bd;F2t@v9Ul)Nkcq7BP%7{=kAi7l`f&YH5^?+ zi8BmO0?yz>G<>mGoUsUoP$0A>{3qmg(2{VDRE#zV)|{aVVJ-Tzefr@GKbZ5{!H+*& ztG;e)GFBS{;*P!a<`-vgt_a?D$4$5^_`!X*qNrLnP6;DMX@_#TTqsvuq+IBJ+-QQi zHUnW_5xpyNCgR7-C60k046>;qKG@`zo>QzH>;Jgi{{3J7e9N=1KlJMF4lYrzwyiPx zsUzMi58nKN{q?Yo6ZUS|)^eq?Z(l0?PyZsGo#++%7g1w0+{Y3om+8{`77L+-tjixzZx zUOUQM482z@7vX~GUJ z$G#%J5&1$`DHC48d&jKSXfO8aW5GuZWh{LO1zuiZsi z4cJ%9xiUOQyTMiQimOGUeR%r-TBum7bKW+b(>5h|UIT6^*3Rei75YB>TfyV0=GuVw zEzCXn$-1TdiHHgn=ZS}QWzxTlHxU72H9a9Y;BG%}0r!;cb{lD5$83&f7R!Bs%3H3g z?L}g)zx-KyzN)u(t35A?8UGpeg1y@quTO7#4wlNz_u_iJnDL*NvXr1Ki2VDLWx*mg zT9z~{W20w3{@1cxtpfJWh!OuOm1%#XWVlaLA71r^cgV4SQe%)`8F<>eNt$mU=5 zO8EK7-QQwgjB{q+8s_c~UVi4#3AOE=H}(17k9=3XcirvlZj7)}h;avpqmNJ)Xhn-S zUlqV_NMSc46Wja+2y0nj7==Zi?6W3i;`XFpf|})Oxg#f~iBT%(nD=?8wZrx-^i5fy z;pim{4=kX>Fs64f*{>||q)1_L;j3>Sz3G!LVFk>;v*nL7mb4t%bw)8b&|CZk7;XOcTWXO;4WM`1ZD~LKUuJSnAF-ShL)vr<$dLiS|9=eZg=Nzc`Di~L1!Yf*%wf+Huvmsq>vCT2ob zFQ)c$&D_~%0qx7;Rn?Wk6X@;r#l5Y^54`l^yBn{c_2jJaQ~!0t@BaDJCNYY4%=n>UpxBxhC5M{v6xj~ zh3;7-H3@Vx3*r5&uv>0Yrl+_hFBwOrvHHicGhcQ#>`2*uAB-ZtGwruOtVvOjn-wrY z%bkyo?g5-i!Knb$EZ3lu&Ck7J-{g1ScK6zOD(~;3R*$JY@8Q|Ij=gyCQg_@UbO1W! z;663x;)%HHUzoqTwDA6$;1nSB+BwIh7cdtbMK2U!Kch6OOSgi&+}!jo1unm*u&9e0 z`BdohnAZyedHE?&HL72Qbc8fm02PjJ5E?p<}_ytF;;&5$%&(f zKi;khSP)va{<5FT{p$fj3*x%SyCU)FE#w(aQd_gGk- z{II`vlQMe)S>1B7v(vf-j6_dvcf><+VWx4p5C#c~f48)pd|F>3D*t~gv$(sUXRLe_ znB|owhWlNt{R{MW?L!-`R<)}Z-M69Pp+hgcd+6u$A81~$dcAhrj&Wm$tsc2?^)t2c zMQdhm;{G{WRy+MAJZ3$EmJK&{O)coswJS~$Bb-sT7w*SknKCk98y-0+7bo(fTgj2p z8WU(}#x&JMjbnZL24EkHIs9YTh2lQ01bamH^3mtsFk@(Aa6naK&we9A`d{ZQoWEfE z;pbm@-3{yA@|0or?kc6#k`Plh zDc$Ja&ErYU$-yz3oMa;_6=(F~Q-8oM9ZM^|L?Tiv`&W6L?RrOMFM7B6xxLRHvS00J z+FPJju33roT%E}2D~I%kAK3VC_f$MSWod&O3o^?nK<3t!>y;7i3$TU5nCKtT@==u$&tfc@$g=3WF}{%`QaW* zs5xrgfnT{F82vD*IA*TSE!ihx?;6`YN1E`(-G|$rz#0c$We&A9tXUNubyTM{-1LPP5#}_Fe!h4h~H|byWEJoPm@`XCiKt$>o{;6mJs56rX)e=5hQf+w~#imYj<^{TNB|X!j%Spfqv!p;glTsPr=NgptM9c z|EaljXgG-~B9i<6rlCaYND{z}HnE1-tJ!50jFd2=iBBq&av1pu?83vte%GM2W{W@p3nWz-xrFu zuioYJ72-o2zt`+7ojf1Ua(&6?({MJbqvzvUt|iXt?hy-$XBA z{XFU&X>p@Jvy8U5FC|v8rLM0cHO%PP;%KRtVkKMZ+88OB<0f0IDEPFwCd$gCGJSwAksBx!1bMkP8RWuLx$w(d^HSR6uP}m^{*F3L`OqK$p?j^RT zuAGf;kpU^k6pkpC1MfVJa>z)?i?!!e+TGjpS?t>PgM7q_8t9PEVi&9#XXJw#xoSBw zo$@R}L7fusknrbI9oNY-n}MI_4+@pe0Idp?VQB%g~|8kswsd=~#yK9nq{ zJWJe5f3!T)DOpZFOMWsR;e02bYu!sC`Sk5nuj!O5C!cFwj+M^P+nJ1gLdiltA}`V> zlq?y6;PR?iTSKy@Q?ihoyy-fOHz8R`l&oNf7Wd4cf3XWBC&Wc?W)HnQmJ>APEXhf~ zP;$_&!L238urt9r{oW~u!P;t;MKAcN90qgV(PMmqUPlg)9Gzuomz?6xIe^tzh7OYB zY}&+10akPJKnb=urRZD_VKt{7YTQ3r56Ac~IoMky;((I_<(DJpSLunJ8=Prl4;c4HU#W9TcMf%-{OOBRQ>Csxk^S!H<;{(6s z_z*1&Z^Ufv^w!Vby2$A*?Q18G7^Bd8K6?wJSb7Un4ss}t_V<}N4Av$)ImF^%oSDPm z=a@rm{%~@T-eMV0j|-g~ay!(+y+P`sOBtlM-gD~VxT8axI(bNMF%SHH`H$6uy~TQ9 zmSQQo#p;3HLfir;2ev-g3pu0pC3=AKZT8kvd=71ir}c|@S|7b7ni<~b&IEgFN~9Mz zpKil*{Nq~6-l~t(p~Wd-%qKp7$=<>*S<5+2ExSa^=;VP~$~Q4e$DMxJ$s=|?%-I)_ znO5?^OnXb`wq9tz>N+O1)Q%xDuQo^nXKVVY&k=86rxT%0gMS+rF3ljqM6&1lc-(KS z?gCd^a?}7;S*&*o#1jYnOJulXDSPLIHBT1p&bheC-gIHV$BUjr%5|d0!2xLvj}OV} z`8xlN@3byJ6obb-%WCW7FneeC0*c`pmC+V$eNf&+5D5+{G8VPK-MLl7U(EOUF!We);_Q zX>%`>+HFMbjz_-QqcMP+nUXOr>2lpp(Sw5A=tTU5YmXV}N5U3BG~OC#TH`}%^# z<9F1Ia-A4>$%Vr*_~9MX=BHhLQKYs@J>Q|W5j1d&Ziz18U1Fx@3j+b!-Z?bXM1MR>tKP7iD?I zdQh_2Xpuj8{W#lJ1WN$o>cz#SrIloN%kP$D#lc#UuO%dC`9|7{SqO9ZM&vBD{}tI8 zh;)q8LXJB-$2$(3**P9ZQaY8|?o~8=@PM4s9!cjXUNWlatik=WOM4_tj=y+X$9DAe z=~mRODmZ5W{0>!B&0c74Yj01K7i%N?HP1_s*i@~sG1&`CMF4?28oiczeUeY4=49|4 z#A9ri(ukC#i zxOnYPe$UmYe)4+}=`cEd@94Be6CfOYI)Crv)GHw$_UC7Q51#T6%LDPZ(tKE8BpRtO z1?D22hbuEPJN0@T{Khz}wrVR8LXGtldkkdc2U5|g40hFW&p5MoP;Jkm!u0+xuJ2S7 z&ypEk%O=O=78P~zH2K<&btsV|AqkL>LaldWT9C1VC}DYE`{6YT!+V(Mp_C1s~qJbo0!M2L^Nd7FB;eYxUwA z&!6SL-0Tgy)UxcW)dFoJZh0YosfkU-1j#Ito9vO{*rMf+98bV)fd!xSt1oMqw$c93 zZp~bqGDCI9W!?X4F6(gQ!pWsb=8+l@*I-ywAn~Uc3rBMWl;K*4d^5nEsp4BU{KCsXwt3LK2`)_Z3@#i<+`07h(n_ehF$TbZ&5R1|M3YVs|ctjwA z1Bp1l!r`%qADZZ1BCo2}ggjnv2||R09`X(DzhSakeyd*f*R_Lt&%aU?AkQ+a*N&q` zSz6D=Ot~nZf%E-cvi;_$N&ezYcy$^*NwSU^{b(me&WJ3EFhRV88QnR67ovh zb>{;MdfvKd;-)E+U;O+2Kisg}{;jU>U8O1)%|3VF&t^4@ykh(I4GW*U{!iFKRj&<5qQ(Be{^wOMoqxgc3)ND4+8w`m?De~TeqqZM z<0t>+hIhX*ylbE8=1brCi=!VG^xRxoh5bEq-90y5c5ThD`NPk_MmQpv*xOw**((8U zP-7k(9qKxQwrYmkNJ+(YV)q!FFo2H|Y=IbFzfs73!i^M+*Y=HYSm}k>MY?&R+lkwX zkaYz(sojlO!X zKdCqjw13|)?5#_l*k`Yqwq-&{Ki>9i5zcsg{@SOuefE}K)y)s6VAqho<39VW3>if@ z2j;58O;QhJ%<1n(UF9gHN9*3`k48*2^wENaMQ2{$p~_G{Fn)MDK` zW)g0*M#rhh&<|tU;}VA)fC|I{km53KdO$_(>@tLlT}5rPuNpFT<~RS0PY6A8<;$O) zerx@Qi|y2Po9?*l{QD-3yG#AGwK;WN7YI%Dxj*~jt>$)@X`;(%s^I3H#vH+T_NHp1pfl^e8SaHMJbeZKZ3a6`npd zqXOj@ ztQf1B5BNNbp5J$9=W>tln6YE}6?vDJ&d4jx>)!MH(GxB$xwxpJv}<8bVQ{kjm5!4W zXizxh89AU0Zg{W8e`L|K2g^Ts=;$Om^hs`(eEwte;0u+2Rx9{mMs z&05GB&wy1}*7V>;tjHY$RP^s+eT@9Q$vLeWTe0)^V)5bMy|@fA0j+}^V)mvpzMzK} z@$Z#f*?>J@@lgvg+Zmem3@-g*t4FS-pk1I$i1-}9$*1o}ip09{=Iyd#H8vpS)dt(w zIcp$ybhY>!bWDARH?BF|qw`AZH0(S2rR{I1QTB6ZtfTN1y`P+dihN~`{TAMkQ(am7 z3~WNDAHzF$d9fOE-a!PchtK#9ENA*CISUtgV~oAudBYni>*+t?jdQ)B*c(lDWJTwS z)@A~9oUI~}l85F|=Tu26UzMi6o!?3}5W( zF|`srZ;=*6^rkOP-=le-QqVdF^pV^ny`g*Lw@#b?Z>{nFC2M9WhpdQ= zJDpnkqOG$Fw#MbL*1;;=ScX=@%bNB~P*Z1luGh4rzJ-vQ!qW?YA?O@#t(F)j)?-EC z)`pyZ960RsD&TP92;#`o`|xBe@f_kfK0lY~@l2n`^aSEW;tl-PO5%;gRm7W!tBDWt zyIYyV!~FU-;v>Xn;xCEYiI4Kl7UE;X9mHP|cM_i_K0|z#xQn=(_#DgjJaG?kFY#rT zXCJ@v3e&GLy`SmVm_EQ94iOI%j}VU%j}hM`9w(k4zDGPs{E*-JnD{C2bK>`c%0u)K z6N$<4D`gQ=h-t(O{xyr(m6%5?l-^Xu#Bx6AMXV%N5vz%Ph<*8HKj{S(CJvVRDoTPH zCbd?S0Yw>56ZqE)h|`Ie5|{AJYfm4?`%8&G=aUuu$_;$7l6WI=HE|7bE#JJIZ?0qd z4&q(J`-t0E>lS|Nai-bJ>L7D?lh4@~>RqOP&v)4J>I0_#O#C0>*ZkJs`R4a*fmWg| zs3ROI@MrRlK2hG$CrKIf3+1=^bUvTM^p*VULL#iK`0H{$UqxI^TtmE#_!N;+s=vwf z5&rfB@efiL{XM4NXZj@5A29t9-~WW^&xqgf$=`|J3L0_pzF{&Q&vXLQlpiC&C+U3B zg_upu;q$J>Z2(=|-@WvTiR!^C=GBXJOM2yrBFG_i?DUNXo?#sof@NSsWZLYziqZyM}PV}|sp zF_So(IEQ#SaV~M5NQJS0xRAIG(qfWPO){!UMm05IR1>zzRG^F_lZqnes9s;LR1nwl`GsR^T+S_@Ga)zpMhO-&fp)I?TIO~#t338R{t zFsi8uqnfZc3ksu}nlP%V38R{tFsi8uqnes9s;LR1nwl`GsR^T+nlP$~_>Pi;Fsi8u zqnetGVp9`FH8o*WQxirtHDOd!6Gk;P8P}#JjB0AasHP^2YHGr$rY4MPYQm@{85O!7 z)555x5=J%2sHPG|HI*=`sf1BYC5&n+VN_EIqnb(>)g+^uN*L8t!lUql`yKQgi%c;jA|-jR8t9~no1beRKlpH5=J$ZFsiA9QB5U`YARt=QwgJ* zioHxmHI*=`sn{1}R8t9~nu;w?Mm5!+`9v7iRKlpH5=J$ZFsiA9QB5U`YLZb+GO9^N zHOZ(Z8Pz1Cn))2cM;AslbzxLf7e+P7sHQHAYU;wMrY?+X>cXg|E{tmGlu|OPsSBf; zx-hD#3!|E3R8tp5HFaTBQx`@xbzxLf7e+O8VN_EWMm2R|R8#*}kc?`QQB6Y_)ii`r zO+y&fB%_*!Fsf+?qnd^=s%Z$Lnuai{X$Yg5WK`1-Ml}s#RMQYfH4R}@(-1~A4PjK% z5Joi(VN}x)Ml}s#RMQYfH4R}@(-1~A4PjK%5Joi(VN}x)Ml}s#RMQYfH4R}@(-1~A z4PjK%5Joi(VN}x)Ml}s#RMQYfH4R}@(-1~A4PjK%ATNHU&6W0?r5bq)0OWa7jpE+zIK0w?|e31FP z&UX$H-ypt8{DAlo@e|@_f+~sVCkBYA#6l^pDkk=j{8dk41+h0VNUR}BPbDkqsbs}^ zso~6LCi*d1T|r#H+^*z13;EZpnO;m>#e5#%I}h@&%}noN`Z?nBe6p9hy>xmCau$A0 zR`2t#A2T1PUf(m_O0)%ajVLozvVMWQuU{lz)GufHI>}A{In&qkog0WZ^2tran~Ap& z*AgFe66GC(y=llyk!-L}jWl`F$dK z_p9fLuMmX^{Yn_muRkhJ(DIUgn(1el-ox}>Nu$8%qAAcrp2*oX)-n~O~$5$ zk}Lqq*t9q{Esjl#W7Fc;v@{u;mL_A<(qwE}nv6|Lld)-OGBzzu#-^po*t9emo0cYH z)6!&YTAGYaOOvr_X)-n~O~$6B$=I|s8Jm_SW7E<^hAoawT#aH{#-^oYY+7hBl$K-D zQZhCzj!jF+*tC?4O-sqxw3LiZOUc-@I5sVgO^ajGQZhCzj!o=^Fi#nqmXfh)DH)rV zlCfzi8Jm`pv1ut8o0gKXX(<_-mXfh)p{L}Dj7>|4JX;)_7RRQgWNcdKJ9$&arln+T zT1uqX;@Grw8JiZzrp2*oaco+;j7^JU)6!*ZTDpu)OP8@}=`uDgUB;%R%hn{?9GjLQW79HZY+8nl zP0Nt6X&Ev$EknkpWysjH3>ll2A!E}rWNcc7j7`gsv1xH^S{$1e$EIb-*t858o0cJC z(=udiT84~G%aE~Y88S94jFbhirMrnHu^4X_V$=x20tpo9D#X|kl(AEYQS&%3Oq3a| z5Ti!^dN*-BaRc!l;=RO;L>V207#;HdLE;<4H;JP26k>D;iq2Dr(E-Hh5cCrR#8je; z4#bQj_LcHb@(U^Xg^+yt)%SefO0)$jfrYwPex-}PR0ui5o9Ge2QN%ICvx(;r&n2Em z{26f)@qFS`qLYubb0OQgknLQ^b}rJA@%19jA{OHPBDCi|Aa3dc!^Ap1uV=b}C|Yz8 z)>DEv5@m!IVLc@%8g&skM{;46p6wqGeJsAF{Py#<5!-Dv=n3f3W~H8WBdw=v=n3f z3W~H8WBdwAJ|&cj5=uo0*6H#@q@sjUQ9`LG(L^drFhhL>l>REgDqEh2RFqIEO0de7 zv`9q>rJ{sVQ9`LG!P-`yi&T_QDoQ97C6tO1N<|5!qJ&aWqWBd`MG4l1@+*;w5{xE6 zk%|)VIgnCOLa8XBRFvo<6(y945=uo0Rul3>q@o1t2tkpG6098rMJh_LUJw+iD8U** zP^6*+tc9;oDoQY#BrQ@=3JrWIG;z^?%Fud(;$N+dZCJ+kDP#MTv3<(eK4om5GPX|{ zTc(UHQ^uAlV@=CY7vzSz2ufYbSeG)^rHpkcV_nKvmonC+jCCnvUCLOOGS;Pxbtz+A zDk#Ynl;jFZas_#{f|6W8Nv@zIS5T5GD9II+B_v$ZVPZY{w36*m$#$q@J5;hAD%lQ| zY==s=LnX8?$zc=m0pe!jgUm<9dnH?`lC4z9R;pwxRkD>T*-DjcrAoF^C0nVItyIZY zs>Db^J{T#2JtTi?>S$sVa>k5sZpDxDsIZXmf`OuU3Ri+CyV zGU64)c~TyXGQow!btq4e>;$(jVEZ6PR*>uzBs&GkPC>F$kn9vBI|VuVf*gH8j=msA zUy!3O$k7)hI|VrggB*iFj=><=DM)q-lAVHNry$uWNOlU6oq}YiAjfQw>=YzB1<6i9 zvQv=k6eK$Z$xcCz=paXQkRv+C5gp`+4st{XIiiCc(Ls*rAV+kNBRa?t9ps1(lAVHN zry$uWNOr2$lI?$CKi(o1LQkt^D^;_7s?k33WF=8F+iJ9rpy;>NXdl6siLVg%3$pIj zta~-`u%h77&YwCB!mfIk6Y9l2}Eo2G+3mYuNiW?EM<{ zehquShP_|IdeyM^YgoG)_I?d}zlObE!``o9@7J*RYuNiW?EM<{ehquShP_|I-mhWr z*Rc0%*!wkXff}|z4O^gwy?f?pk?h(?a5T~+iVyh3Krvz^#img6`o)Q#WeTbYKA}5E)$suxb zh@2cECx^(%A=vZf{fAlpZNx{2&BR|4w-aT(7J@xr@G;^J;;)E1iL!PJ!JaSpEO8fc zH&NE1A=vW;_Yh?@7t&r}?Zm1df>mEy@)f3EWqLo;uQ4riLy zc792VmKcJyU(!d3$B43j7lO54P^`EiSo;M}5=E;F!R9YdM7IpV@-Jyw(S%_Cm-J^$ zf6nyxQgY=X`iO}{S@ncevb@8&DWoi>MI#NV6sAQl4XHGyGx)14Vpov?><$RZ?m&pU z10n1V$hTy?hm?%>kdpBpQZn8{*c}j*IXa~3MM6}6Vk1%Z2twE+K&xVpKu~745OxaW zxmaaG>J*=}3F^B1N;iluqG(njYE~gw+VL%nNBkC+cI3txFa&$MJee+k#W+P8)@l3| zqgB$mOpA3o1naas7wdEgBUiAPPsBPMGD?{)W4Z^^Vx0~dJ((8kbO_dI$)S?z-b`09 z9b{Up(;--=<(V_kE{_wMibMrQV4N24;dWA zoYO-FM=@vi5bW6UD_J{)V9k~^$Feb*X^v%M3e&Qh2*JKB?}!!=f|Xm+P8-f(OU@+D zCe9&>Ei?oxx8QvKN-W#`z+K0I7O@bzK|k=hAbi9CZzQfF-b7qYe3|$Palas#83^u0 zZs>8riSh(}D%hQvM=T%~5le`;>5X^FiMXGObS1HhSPiU2IX40=qOfZ%*!6K>G5;#s zS}oXBP;|3e@al2kFrvt9tu}&)TZTx(PYLiG;y6A(m+A3LpU3nBqST@mZ6e=VNxYG` zig*)oHE|8!yqmb5xPf>N@m}Ia;#Pj;Vd6I8BgAInFNxcUj}lvmj}dnee?{C$e3~dW z(poU5;4b2B;&c4s^Ta*Gy~LMU=6!reY_PT136g7NTIj1fuaGM&eCKGOwE z7ZF95sD;KNZyFimlzb$gjAD8;(_@%!V)|^RIljPnk`Koh7*En1Utl~*vz5Sj zlAgq0iS|;9)s1{bw3k|}aU?yBX|^F4Po6t%ID>zkNyPbIJfB0noH!R4CVPa*9%1Tc zVX{Y<>=A};ChrJ)gvlOZvPYQg5r$TF9M7ef!{X@?DC`j?dxW8t$#bb)7+RU6rFLOx zWrD&UVX{Y<>=6c|K8`2C9%1NRg2EnQ=w0%rutykrm!Pmm7{M;PZQB$65r)Pk&xJk0(6}Tm z>=A~>B`E9>#`y|CVUI90E{M;L1y{0jOK$_#x;(!w5L=u7fM*dt8#2xHYFX=7n=gvlOZvPYQg5r)1be--u!lRd&@k1*LIjNN>BF6=7n=gvlOZvPT&DlH?%l5hi{M;Q8& zJQwx|lRd(Qut(Ss_6XxtfS|BP7^eaRg+1!P632nkN_AifLE+3gu9fPzR;uG#sg7%< zIbT;l<65JR7OFa~8tS-SsN+hZjutA!m6fkR8U<5{!bNq| zoa<;cs-wCmMwF8P_25Q9nGx#2jr)LdeykqcD9`2mSUtE=(sF*R z9^CjiP|lClYf_SWFr<8OCGke0oUW+{Lkh|nn|ii(JzKk;tzFO7u4il4v$gBl+Vx;a z`PRe4ZNx{2&BR|4w-X;F$}WFB7*cQt@mIv1#HWd}t5^?)6qLQudN8D*oHVQFNwaz| zq@?AfSv?q1%Dj*7yu$RWOz&ss zXQBKhx|HcMrh715&U8GvzBa zO!p=BBZi6f#75#EBJ0kPUJuTc97ajYfHNgMhUq4z&u01@BF7yWpx)rPBM;PrGv!yZ z#;gZtN?P>NdT^$sg&FF>nUdzH1ZPTG)|mC+Oi4R!C}&ga!I^?`lByn@DJUnY>cN@& zv<9%pS3uFM8o(ZcHAK;K8mQ+qP|sJJUn92%%IG*DY;;OyVP zdB1@(ego(F2F~UUoW~m=pZE$SQ&6<@2F{)hoP8QN?=*16Y2aMbz`3S@vrGf$mj=!( z4V+UNIGZ$Z9%?(tY$TrI^EN@|KU8P_T)z*)?T0dL7*3S}buTddZ~lX`868Hc?+~qQ2TheYJ`DY7_O< zChDtA)K{CRuQpL%ZKA%~L~XMPmOaT?G|VRImQBK90|E9}2xW zj=leXNP7SHIIp|Tcb<8;EEh^vh;oCN-WR)&PM)^LbqfeLy}Z0H#1ggzdK-5V8l_E~ z+w0qO*UidlShJK;^s_3V?WXz_#nNP{B)hW5FDEOzMjlD7JRJ=}Q50dX;@^e3wrK?m zQXOVS&y4Qp^X@;N*Y|bw%yZ89e9!ru?>W!WIS=9ehw%PGc>f{1{}A4P2=70H_aDOh z58?fX@cu)1{~_N0&=22__xF;^UUJz>E_=ykFS+a`m%Ze&mt6Le%U*KXOD=oKWiPqx zC6~SAvX@-;l1oNy?4d+PZOrKCF+(fLB;1NJw4w|%vJ7o0LtDzwmNLwbGR%)M%#Sk6 zk21`UGR%)Mw6_fHEkk?D(B3k%w+!tqLwn26-ZHee4DBsLd&@8b$}soIFzdJXK48uT7HI>pP}VvX!#jheukF+2>SL2 z`t}I=_K0fqj>Jc46(6Nl=oEFu03TKCYV@k$N2&Wq6%{B220p6T;6&n4e)TB7dX!&1 z%C8>fSC8_mNBPyG{OVDD)k=G7rM~nO53ND{ZEgHq%O*X{F7y(q>v|Gp)3ZR@z1@ zZKIX8(Mo%0#rv)Jt`*<4;=5LS*NX32@m(vvYsGi1_^uV-wc@*0eAkNaTJc>gzH7yI zt@y4L-#rG~z7tuB1KZj$Coen(+mFHaW3c@gY(ECuA7@l;m$tMe+NCW<&q3N1MHsz5 ztv&HxY`4btg!iYlC%iwcJ>mUn?FsKsYiFj=&P<`5nL;}=g?45N?aUO~nJKjEyQH6Y z9Ny0Ctex3eJF~NPW@qih&+W|4+L@iTE7H*O#KY}@BjI*M8b*KbYuDFIqxYw^2i`T^ zuCJL!t5&T4(7YbVlcSFGZ6$9V0ERg4+X z5nVg6Tsu)*JMmjPkz0HCwBH}Lf!+t$uCJDDI*;BwcffN8Ja@oz2RwJcb4S8FcffN8 zJa@oz2RwJca|b+kz;g#YcffN8Ja@oz2RwJca|b+kz;g#YcffN8Ja@oz2RwJca|b+k zz;g#Y>(G0b9G*MixdWa%;JE{yJK(tko;%>V1D-qJxdWa%;JE{yJK(tko;%>V1D-qJ zxdWa%h@3m%xdWa%;JE{yJK(tko;yPG+yT#>@Z1T{o$%ZV&z>W2WZ{sg6A%H?tdr;cfoTPJa@r!7d&^ta~C{!!E+ZpcfoTPJa@r!7d&^ta~C{!!E+ZpcfoTPJa@r! z7d&^ta~C{!!E+ZpcfoTPJa@r!7d&^ta~C{!!E+ZpcfoTPJa@r!7d&^ta~C{!!E+Zp zcfoTPJa@r!7d&^ta~C{!!E+Zpcf)fxJa^NcyWzPTp1a|>8=kx2xtsRf4bR>1+zrp& z@Z1g0-SFHE&)x9c4bR>1+zrp&@Z1g0-SFHE&)x9c4bR>1+zrp&@Z1g0-SFHE&)x9c z4bR>1+zrp&@Z1g0-SFHE&)x9c4bR>1+zrp&@Z1g0-SFHE&)x9c4bR>1+zrp&@Z1g0 z-SFHE&)x9c4bR>1+zrn?@Z1B>J@DKE&pq(m1J6D1+yl=&@Z1B>J@DKE&pq(m1J6D1 z+yl=&@Z1B>J@DKE&pq(m1J6D1+yl=&@Z1B>J@DKE&pq(m1J6D1+yl=&@Z1B>J@DKE z&pq(m1J6D1+yl=&@Z1B>J@DKE&pq(m1J6D1+yl=&@Z1B>J@DKE&pq(m1J6D1+yl=& z@Z1B>J@DKE&tG6?X)g@-!f-F#_QGv19QMLtFC6y5VJ{r^!eK8Q_QGB-?DfK4FYNWg zUN7wR!d@@z^}=2+?DfK4FYNWgPcL=vrS84dy_dT8Quki!-b>wkse3PV@1^d&)V-Iw z_fq#SQpZ07p9B9Kd_Lj$`T2xnv*)$yyC(E*9sVDkL^VY{s zxjuHv^}$;oy!F9bAH4O!TOYjj!CN1^^=a)?Z(yffAH4O!Tc7%x-Vbkm@YV-!eel)? zZ+-CA$4xZ{~cxZ{~cxZ{~cxZ{~cxZ{~cxZ{~cxZ`icpHGX0eBmLw*hz?fVTm78-TX~cpHGX0eBmL zw*hz?fVTm78-TX~cpHGX0eBmLw*hz?fVTm78-TX~cpHGX0eBmLw*hz?fVTm78-TX~ zcpHGX0eBmLw*hz?fVTm78-TX~cpHGX0eBmLw*hz?fVTm78-TX~cpHGX0eBmLw?TLt zgttL>8-%w(cpHSbL3kU4w?TLtgttL>8-%w(cpHSbL3kU4w?TLtgttL>8-%w(cpHSb zL3kU4w?TLtgttL>8-%w(cpHSbL3kU4w?TLtgttL>8-%w(cpHSbL3kU4w?TLtgttL> z8-%w(cpHSbL3kU4w?TLtgttL>8-%wZcpHMZA$S{tw;^~Ng0~@f8-lkXcpHMZA$S{t zw;^~Ng0~@f8-lkXcpHMZA$S{tw;^~Ng0~@f8-lkXcpHMZA$S{tw;^~Ng0~@f8-lkX zcpHMZA$S{tw;^~Ng0~@f8-lkXcpHMZA$S{tw;^~Ng0~@f8-lkXcpHMZA$S{tH~l}Z zMk4)}9_aB@yX~ZV+6^Q<9EP`Hc+t4a3_oybZ(KFuV=J+c3Nh!`m>t z4a3_oybZ(KFuV=J+c3Nh!`m>t4a3_oybZ(KFuV=J+c3Nh!`m>t4a3_oybZ(KFuV=J z+c3Nh!`m>t4a3_oybZ(KFuV=J+c3Nh!`m>t4a3`u;%zPQqIfgjCr(}zC&mu26YK)J z!5(lPEPzF$YA00r^&XYq=p8sOs{F>E2fgF#MU~(9cJO}i9pJk_?*w~MbA)n^P|gv`IYK!{DCY>}9HE>elyih~j!@1K$~j6o zM=9qhPw1q@g9k+m@#^f zL{`igy+)S@}k;t+~BFi3$EPEuf?2*W_M^%}$ zdDFJ{NMz+x+ukFQWmc8d3b}3Xk;rPD+_v{fWVKpu+j}IkS~IupJrY^1nH#-FBC9oX zqxVQ;wPtSg9*JzidnB^#k;pPT%j%npQ~nP84tNvv9*Hcc_hbX_k;t+~A{%&*M3#A6 zHt-&aEVH?6;5`yq=5*P>dnB^V?6QIPNMr-=k;n$#BascfMK(SdM zy+T$NcMEb zmOT>L&@1X$_DEzye?iNJ-XoC>y+BFij0%N~g=dnB@<_ef+z?~%x| zMR*yF0dQy0q4O2STr)? zzr=|D5+nXgL5tJ*ud$c-ud$cpeWl3DM*r8?OY*Go7s0oK_k-^M-v#~>_-^n$;4cgR zLhDrPLVt1oi{!roy-VS1q<@X{uaW+>q|?VpA0vH?^fA)MNgpSDob++hCrF*OZF2~8`IJq1rm*eDeoLr8R%W-l!PAoa-3X_lgn{(IZiIe$t6cF zIdaL7OO9M}vJDE~m-mG`XB6m(%2Onp{qk%V}~sO)jU& z2#|fH|np(pAb%y`!u;vllwHePm}vJxlfb(G`UZc`!u;vllwHe zPm}vJxlfb(G`UZc`y5}2=lD`Qrzq=0Vop(((NWeMUyA26ekp}7#d8|PP9)AzwsVy2 z9A!I4+0Ie6bCm5IWjjaN&QZ2=lF%wr^6lZ&J2zQnqhW zHlMxyj>I=9+czoOH!0gUDciit)|Qx8*^G`4=ZO#JS+}1jN}MN3oY&mY&-gpkyyk{R ze}|eUikoN6d7d@rdDfigS#zFe&3T?R=XuQv{k*?l&l4TZ6Bo@B5zQ0f%oE$p6V=SK z@;pz(GEb~BPn0rGd@`@Oq{^eYq|x86=L3Jgp4VK`_@HyqoYCq2em$=_qfm23{Z;Jg zS7OiTh+>`*d7iO&o>6$7@pqo_cb<`Vo-ucx(RQA3cAgP-p0RbFQFT7__v`u4->>I2 zXEgfzwNA&>XreRQjQH+6zAM0g0saf{Ux5Dt{1@QA0RIK}FTj5R{tNJ5fd2yg7vR4D z{{{Fjz<&Y$3-Din{{s9M;J*O>1^6$(e*yjr@Lz!c0{j=?zX1OQ_%FbJ0saf{Ux5Dt z{1@QA0RIK}FTj5R{tNJ5fd2yg7vR4D{{{Fjz<&Y$3-Din{{s9M;J*O>1^6$(e*yjr z@Lz!cZ^8e!;Qw3j|1J10!haF|i|}8B|04Vs;lBv~Mffkme-ZwR@Lz=gBK#NOzX<(U+FT#Hj{)_Nmg#RM^7vaAM|3&yO!haF|i|}8B|04Vs z;lBv~Mffkme-ZwR@Lz=gBK#NOzX<(U+FT#Hj{)_Nm zg#QKjUx5Dw_+Nnk5}cRdyad}N*e=0p306z6T7uOQtd?N41gjQV50;ZCD-6FMHq;`wcZjst8QoBWJw@B?4sof&ATcmc2)NYa5EmFHh zYPU%37OCALwOgcii_~tB+AUJMMQXQ5?G~xsBDGtjc8k<*k=iX%yCrJ3MD3QS-4eB1 zqIOHvZi(70QM)B-w?yrhsNE8^TcUPL)NYB|Em6BAYPUq~mZ;qlwOgWgOVnXXrgqEJZkgIGQ@dqqw@mF;h!9qY5LPssTT84Yy!N}2@Y?T+^v&pR zf-6!v+g|%!(Jap?{wBDhRUMzoo8do@n&9)D_JW zjlT%`Tk1;aZ-OhD?;HJ1a7A-`qrauDXkKshH^CL@nBFfPGx}TV3TwZw6J@-ciwb;Va>!heVT@AcmTuO~hT{vP-t@Cp8U8~g9I^Za$~>Sj88s_+k}btm2DRe6flzR`JCuzF5Tx)F!7a5^0GD2M>y8fT!rPJlr5_HZn=#`c=@>(OWHS$^` zuQl>oBd;~`S|hJD@>(OWHS$^`uQl>oBd<5e>k@fgBCku->k@fgBCkv2b&0$#k=G^i zxE|J$I^14i3SIFxMd0io|E97;BysnVf74o`5URTKL3VB^2 zuPfwrg}kni*A?=*LS9$M>neF&Bd=@Zb&b5Pk=Hfyx<+2t$m<$;T_dk+Sa{DjH;JW^)jkn zM%BxxdKpzOqv~Z;y^N}tQS~yaUPjf+sCpSyFQe*ZRK1L=CgZ{sj3Om3n>;SK@1H8fx@JjfA{~G##?kem6udoBWqSaKV z`2SWa>;SKXzlTk&!;fJ5|5hsO0I!7pf7?pv|I@Fq1H8fx@G87j;jId9Rd&u-;jId9 zRd}nyTNU1_@K%MlD!f(UtqN~dc&ox&72c}wR)x1Jyj9_?3U5_-tHN6q-m36cg|}+L zyj9_?3U5_-s|Mz+3U5_-tHN6q-m36cg|{laRpG4)Z&i4!!dn&Is-bzS!dsP{^Hq4O z!dn&Is_<5Yw=MOu#}ZrWWyZ9AyG761qGxTtM&mpEeoocf3U*@qRJ|>oX>9a=2ySWg^pieSZ%d=6 z(Yqd=|`m3}^TuF>tW(;7al;nNyEt>M!e zKCR)?8a}Pz(;7al;nNyEt>M!eKCR)?8a}Pz(;7al;nNyEt>M!eKCLNkIj@p__T&kYxuN=Piy$JhEHqww1!V>__P+-r!{<9!>2WTTEnL` zd|Jb&HGEpbr!_@BDjPnn;nNyEt>M!eKCR)?8a}Pz(;7al;nNyEt>M!eKCR)?8a}Pz z(;7al;nNyEt>M#}PEl5wb&9glKCOlJX-$!mc*CbPd|Feaw3g6qXKHWT_;eeeZsXH! ze5yM_dB**88=r3D(`|gZjZe4n={7#y#;4o(bQ_;;uHa^|Pr`z~+8=r3D(`|gZjZe4n z={7#y#;4o(bQ_;;uHa^|Pr`z~+8=r3D(`|gZjZe4n={7#ywoi32nf~8UsQ+3LY9=E5 z1yC~)*_w$6H4_nPCL+{KM5vjFP%{zX-`n;~M5zD2(`Bq`Cqn7DP#P%Ie=`Z+3#y&S zRyz?&&xO)+q4ZoRJr_#Ph5Dv1)Hi*hzUd1GL4DJgJq*6c8xDigbEQkqh3fl4^?jkf zp$ql(T&VBnLVX7p>XZPXzI_XC8r@EWI)g&k2)-4Ro-2jAxShz}0ZPwhtM3b?=R)bZ zP^`GyuKLmal+zV#F zM?lRc^o+jP3iYj4$lKgbWdA>)^jx<3zEFK%sJ<^$-xsRy3#I2m>ABGDB*dp7J`M3{ zh)+X&8oKZ68T&NEry)KK@o9)pLwp+I(-5DA_%y_)q5HmmYoCVh`$GFPbl(@+ry)KK z@o9)pLwp+I(-5DA_%y_)AwCW9X^2lld>Xp%2ci4E&^`_EX^2ll_kE?Z1@5TAzlG{mQ&`+gAO)6jiiwtX79?+fkI(0yNM zpN9A}#HS%X4e@E{zOTR9ry)KK@o9)pLwp+I(-5DA`1Hr*({)|5sCj7cV=AptU#o+A z68a`3)Hf-iS-MA_JulR%j!-KtLapiuwW=f3s*X^rIzp}L2s=To>d5W}dqC~9|&Nf2sPN2paDp;mQ-T1gPz4{B9MwpMk7TGbK08`P?fY^~}DwW=f3s*X^rI>Ilj zI) z0B;TO)&Oq}@YVot4PJo>8sMz~-WuSo!7DIIH*XE_)&Oq}@aB6=&IgU~)(CHn@YV=# zjquh8Z;kNQ2ycz>)(CHn@YV=#jquh8Z;kNQ2ycz>)(CHn@YV=#jquh8Z;kNQ2ycz> z)(CHn@YV=#jquh8Z;kNQ2ycz>)(CHn@YV=#jquh8Z;kNQ2ycz>)(CHn@YV=#jquh8 zZ;kNQ2ycz>)(CHn@YV=#Z}mz@a4#eHy^P@Z`osXG{1)gD=U&f4g&&ZA@AYg{_!00g zz^{R0;5aw|9s!SnUk4|_W8iTx2Tp;fz|-J2z%$@9cpm%~xB&hY_}Ad8;A`OP;NO53 z!8Py_sJXw&uQ{yn1~vLy@H^mljlsY6UxS|le;WK55N3R0fc^?6L@f6bvE1tu1A==! z^9}Cxi2=fY1O5V-1|!gs%)Q|ba3`o!!j$6J=3edKGJ5pC*K=p#1EAI%WNY`D@Harp z6Mg{ucR;N<=&$%F#7CYxE5+J%Z}=#vH3!)r2VL4Gyx)ZPoA7=U-fv3S`%QSi3GX-I z{U*HM)!uLNc@aW;zscuC2<`nQpBEvt_nW+4A+-0Kyj~%+_nW+4A+-0Kyj~%+ z_nW+4A+-0Kd|rgm-f!}G5kh;v$txH_d%wvm7(#o$$txH_d%wvm7(#o$$txH_d%p?q zH~G8>+4g>u&x;6}@O~5CZwl=Froi5B@_7+Ld%p?qH{tyzyx)ZPoA7=U-fzPDO+GIo zXbSE9rqJGR((XQ^z2D^XB82vS6W(va`%QSi3GX-I{U)!R=ox#z3GX*~kM|`93{~i?6P$RyRd-$E$kw;&R|!1i6?aiyX-~mzs6p|)*0+d zU&ek7TW7EXHXP3jP@Qli)pmMtw)mGfTQpJ;-(=={kd5_FJ)a2D|Kg`Bf9BUDHa@9%-S@U>EAn zYoT_}3blJysNJ(d?Vc5C_pI<&!C&K@I)hy)I)h!PGuVYXgI!4bRG$@x%(L!O&vm-a zU>9!j+nO<{GuVY8_#>e9ek(?Q{>AxyYldZn5zbaa@ ztuxq#I)h!PGuVYXgI)M`P-n2qz8_m>u*=pN>_VNvE_@fZ&S00VGuVYXgI)M;Y@NX_ zTW7Efbq2doXRr%(2D?yaunTntyHIDa3v~v&P-n0Ubq2feH^Kklx=TZx@QOk2rlrxeG@6!1)6!^KS|ebao^hK=qiJb0Esdt7H5xkInwHj>Xxo~WPFT~@ zXj&RgOQUING%by$rO~uBnwCb>(r8**vk$+=nwHk=!)Q(8_Aa3{joZ6~)--PK5?a&J z8j=0HH7$*%rO~vsMr5a0)6!^K8cj>1X=#nf{*^T?ji#m1v^1KQM$^)0T3RErpRuN; z(X=$0miE08O0lM;(X_PYN`A(gmPXUk8oO;<)6yEjZClgQ8poYtO-pMuw{1;JYfQIo zO-pNJw{1;JqiJb0Esdt7HL^S1nwCb>(r8*5P21X=&x7mWigN z(X=$0mPXUkXj&RgOZzLcp0uW=(X=$0mPXUkXj&Rg1X=yYqji#m1v^1KQM$^)YbL3ex zEv;zBwlyt{rlrxev?3p;Thr2LS{hADD++SDH7$*%rO~uBnwCb>(r8*5O-rL`X*4a3 zrlrxeG%I6iG>u#5^fqf+8cj9;|4k*y%rA8n@I5t!ZgAEsdt7(X@1EO-qN?w6y-8#b`}Sht{-oXiZCp*0i*5Ob+fx)9y#p z?nl$^N7EuSEke^GG%Z5YA~Y=`PK(gA2u+L7vR(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBN zEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2LenBNEke^GG%Z5YA~Y>R z(;_r2LenBNEke^GG%Z5YA~Y>R(;_r2B2J6YvCP zYr#9ETE_dd#_~?7gs}tEe}BvF0`=eDvU@=N_qS~Q_qS00{T;khtwku0>pk+g@%Nn~ zpBjH2{I}pQf^P@!2le0IdgfiA{`*_D{!3k`|56v~ztn>rlye8=+(9{aP|h8cbBEN- z&$ygBq-I8!bBC0{=yL9$oI5Dz4$8TMa_*pP8C}jDYGX#1a|h+z zp%!J^<=jCzcTmoqlyfKL+(|iiQqG-}b0_88NjY~?&YhHVC*|BpId@Xdos@GY<=ja* zcT&!slyfKL+(|iiQqG-}b0_88NjY~?&YhHVC*|BpId@XdU6gYd<=jO%cTvt=lyev5 z+(kKeQO;eIa~I{@MLBm-&Rvvq7vPDZ2s?mHQUl+(8;t_8kD z(dhQ+TNI6MpT0%WXutawMWg-hTNI6MpT0%WXutawMWfrN?-^VZx*z$TL8rK!zC+OH za{3NIqs!?#1dT4IZx1xOoW2cENI8AqpWa3}eczwbDW~uIv+Z*FzCWYO>HGeSE~oGN zGrF9<@6YIRHmjUEQ$yu6dNrw8r9B}`^H+cSZdR0H^q1~t#V2b*udFsFyyo1T_-)W% z9GVrM7(WbpWxF}C7yBdFx-~{A4})gAS)4ep4zLr{tuac`tuaE~8YArG$v#lG#wcX~ z)U7eHhrnUbtK7}3b2hWi*~~g;GwYnqtaCQA&e_a5XEW=Z&8%}av(DMfI%hNMoXxCr zHnYyz%sOW?>zvK3b2cjiaqf9=2Al*39cJ^Wj*iZ?6v zu!j@6?-_{>*URfJ^U+wD`{5jVfSx8!EU9=5&G-mKWew%6O66?@oj0^Ks3 z6?+)n_L>!M7~S@o1Gl|q#T&+71zXGvYqrg-*)}V#@Ly?HiYsKR{i}Vd{Tm-4MYqPt zcAVd=$idHeg}hmjgKYH<{gu_-X7v%<|Hgk+PqFQF{$}+T+qyMI=(W>k^%~m|wr-7) z?UjdS^&s0juyt#U?48)}#`YJ1X7wqjd)>8JJ7R+5_)IrweIv^A@(rOUgx*EK z-Jrp*vFiS7@|{vxd-pwwCj#Hcr_(?6q|utQTbg6rUf9jdXty-SwmIA_&C!WJ(j4Q1 z;BSNGYPU4!yig~N2zBCtP$!KDb>e|gCyfYo8;el4u?W4cZB2&P8t#F zq!FP`8WDOuXE$@7-OPPZB3b$H5$^lSY(s3e-s>vcCbI0jELT#-j8*sM}a%>oyjlP8t!O=NX+eB3mbo2zAnk zZ~?nSjdaq8QoNG0Tgqd53Hw!SujK5O@;Lo<@NdA2;2NltM)X&mG$PbVBSNoE@0Riy zzYXf75!qgy-mO`W(W}$DHS00zHkM$wl*g#sScE!hM0k(?s#%ZT$*gC$l*e`>=|7GA zR_vd_zL#I=q!B&iUcXz)W7KUdLfyt9d^f0*Mr7-x5#g_b?uolK$1%D;`i4hwB`tD} zv^VBByQM`=(QPb&?|;-YYRSe&{2qZB3b z`$65tB3mbo2z48aP`9xJ??a2;hZgxJ%@azo7QGLJc^_KzKD6k4XpwI)JP|yA7CnF# zJ;0N`HBYA!qeZ?oZ%wwf$hYPh&5v)*Gg^xtNVskI);#~!TI5^vjON6*=GitUzBSLb zwaB;T*>!7WwWxqqWF)=NYX^4)nxYmx8HGg^y$cb?H&W9O;1mvMGv4wzD-Zhphdn-&$j!KZ`0G0XpwKzvu!Q% zZF;t?MZQhXwzbH&={dz(^Z;7q+w^Q(i+r1&ZEKNl)3a?Y@@;yytwp{~&$hM5x9Qoo z7WpzD>_)E%I%8#{b}2qeZ?=&$hM5x9Qoo7Wp`8GYHwaB;W8LdUW zO>bTJPSCTb_e(vDp3C?)J)`F`zD>{Qxr}eqGkPxL+w_c{9r!jqqh|!ZP0#4q-nZ!) z9nbqVJ)>jw_p5yx9iP9SSlYMg$tJ?|ZF;sHRr)qPqvJ{6re|~v>D%;-jvIZOp3$+Q zZ_`^3xc5rv+Hvod(6#$@YRA1-vRymwy%M^1+})l z-5zSU2jA_Xc6;#M9(=b4-|eAxd+^;JYPSd9?V)yi@ZBD2w+G+tp>})l-5zS!qCLQE zK}$j>w+J0?x2UE@-8>@nNY|qJ8g+7uP$#ztb#jYPC$|Va616ZAwGb7zFcP&e616ZA zwJ;L3Xg8*xx6Zeq@GWS23##6NO1GfTEhuvfn%siwwxG8yVne?b8%FPPX$jJxPHvH{ zlUsy3xkYGgY|&m#r|aYvp-yfIT9P`sMfk7$tK?6B?$Ir%N(*|@f|9hLAuVV~3+mB= zZnTI`KX0vQK_yzyhZdBfC4AcN58FVU+#>tS%7uH=gg>s9^P9@u_!Gi^&mPVPiBBFR zK6y~_##->8*gh}x&fy2ew(d&l*IiC+iXN$CJP!7i{H>;bbpIgecci$<}h_lrHF zcU(Ux_Kf7k4%i3T0sCOEhx8VH^%8a!^v>Z2#i~%O8a=ankT~i=jXTOkDR}>3y#H|WBT8w7|5o^K4Ib9>t$|xbYw#rKnQv?G6!w3{Zd2~9 zdcV^@L;ADWhrllwVWSl`T9wOs;9G&Zgr4U8{0ND*1WgANaSy zA8Pb@Ecmag#bd!Ak^WimkHOFJ*FVMf8row)Cw4d31NMT?@#L4lFN0qJpXaY%#qP%* z0EfUANFT<2(MY7>JB(D?q}O&n7PP6%AA^&RiD#uy>yOJvYr)6mBcYf#{)F&xeD^rM zdmP_APOTr;d)k7>@!jM2?(x9BdmP_Aj_)4FcaP({C-B`9`0fdO_XNIs0^dD>*Pg&f zPvDU!@W?)Vv5#-E`|!v<{r0h7pMGn667-n9Pj7I_0qkeQ!#;V$>3^tl?vqEH@<-rj zRnC3EA7g)xzkXgd-51y|`+|1TJ3+5!?hAUbd%-XAYG2YjqxSK|Z699Shu8MWYbsUJanY0b;z@k*B))hOUp$E~ zp2QbV;)^Ho#gq8rNqq4nzIYN}d_uon4?dya8r^#LRkCqEhdH{ny% z?kQ^b6i+_IlTT5*r>Nai)b1&2_Y}2zirPIz?Vh4`2dK*d>T-a(9H1@-sLKKBa)7!V zpe_ff%K_?gfVv!@E(fT~0qSyqx*VV`2dK-_J|Q!B+9zZNPb-&U;p5jkeuJ+inZo zw%Y=??Y6*eyDf0rZVTMD+XA=kw!m$>EpXdz3*5HbXxnYH?KawW8*RIdw%tbCZli4< zgpGsna8NvS1qa20(W-lp_Ha-<*tY5(r2QO3bq}Jt2T|RFsO~}Wa9+qSgJQsF)jdev5326At-1$QcmLI@dr-BuZPh)fS{tpp2UTm^R^5Zt z@gQ|Pi0VG0+6@QKsCGiyw=x5xs zp3(dD9=+fA5v6|yem(;;pMjar(6c^6&w3VapM~3JmHUa{S>oriemA^dd+e;vYKhbYe>{B?*@9imi+@Yf;ybqIeQ z!e58**CG6M2!9>IUx)D5A^dd+e;vYKhw#@S{B;O_9l~FS@Yf;ybqIeQ!e58**CG6M z2!9>IUx)D5A?kaG`X0hxe;9m0>)U@MMOqg+8vG;ajM35HXO(_J_~S-+{wzFyR?jF! z&zuN8#~VH`mQDnp7fV8X_j%YD2Ozp00QL2nc4SL?#hfmWd}pfF$18=UUieL?TB z{T0x)`-0x)loyODgWjVubOm38$uGj>7h&>?F!@E8e2!W_N3EYj@tz~E=V0JD82A#; ze2Hhi#4}&wnJ@9omw4tY%4I$HigFR^{l>QlzshgF%5T5QZ@BxL{H%YQ{5-amb|g6nz6c%xzwS3DCwapuo#G zkA&9hk+1>#UgsYEte*6Z09``=ABXP+kR4>59*pVv(ZK(|FdCe|cD+Ue*JU&~3+AOK zqrt3y8!Yixuau4k%e=??Z%2a_o_rl#<*$DOx^|<%MV|bh*j_;$4c_2am#{B`-lIDz zuQ``%;B``N@Xl}Z%-@242Yv^<$&=s3z6IXq`8(KuFCIpN@9~~>QvLz^A1TiUxJmk5 z@J-(KFW42MTD8hU3@}Oz;M)+yo?5l>Q+`|WKl0>%a=uBA@1w~!QV#N0&(KGc&ywGGbqsdcl z3CYv^>I^sy=6Qw|l03&7=D`B!b@O-~KPs|A{C68G8eJ6Z;3))`Zby znYwsAXEf>coY7?6ZwM2hN2}5BNBv~zF=#aW-~HRr>sq6s*Lg<6w}AKXq{qk6&{5N9 z*ywtNZ^icRh0*Z;;K`qLF5%B%r}*pJ^kkO4nWYbA>4RDIzBQ#=$FfPcv@9(rOFPNZ zLb9}tY|^bFn{<1~Chf;;(jLspFGg!lHu)`Z0kraDlV&NKG(Xv-naQf|Le3rN;uR-&kOk9z&(a)ZhJ#Yd3~U zj|KL~7%Dx6N{^w^V@a#@7%DxMv`UYm(ql=h^jOj=J(jdekD=0INvqkITCCsp4Qwmh zSkfvzmb6NbC9Tq9Ni#f_v`UY`)mV~p!q^xpJ*L*^XROj=YAr^q^jOj=J(jdekE!Jt ztuqp24u|7#I1Y#7a5xT!<8U|*hvRTK4u|7#I1Y#7a5&CLHx7s6 za5xT!<8U|*hvRTK4u|7#I1Y#7a5xT!<8U|*hvRTK4u|7#I1Y#7a5xT!<8U|*hvRTK z4u|7#I1Y!t*Wg6pdkuteI01(fa5w>n6L2^IhZAr(0f!TCI01(fa5w>n6L9GJ5%f+t zoPfg#IGljP2{@d9!wEQ?fWrwmoPfg#IGljP2{@d9!wEQ?fWrwmoPfg#IGljP2{@d9 z!wEQ?fWrwmoPfg#IGljP2{@d9!wEQ?fWrwmoPfg#IGljP2{@d9!z1X=5%lK>`f~*R zIU>f^f+O&A1Qj|W9+ZL>9YKqZphZW}q9bV05wz$CT66?0I-=V7S5~AWs-4lgbVRx| zEc6(0L^XAad)yJ!=?Lm{1a&&1dO6)1bp(w%f<_%dk&d89N6@GvVUuFuqr^W)iF}T# zc1j`gIZEVnl*s33V68Z+TKliwYj;$&J}>+$>}7fXXz-eHJgRuc_8Zt&!0VtD?5N@m z}$=y_D5r)`g(M>Trd_K0~@ zBc>RT2UQo1l}`UT(4*wh@NN35ZzO3GdiwX*kdQ$z`zxDVsseauh{7Z0#XD9=G zd6L#XNnf6X?MYhuB&~gtemzNRpG;E1b!p7(qt7kECBlRo%8j!|>c2iu;HIqh0ie`$)WQ(<|8@OKF53{hvw&)kK~e`kK~w-@sxR}AT=E3zo{!`hJ90_SM{uh2 z19NC#j`>I~>G?=5>G?=5>G?>G`AClWNRF{Am-Kuj$B33odOnh4T+1arAIT*h{pOgD zW`so$MIc}}1?C+V{%>6<6%n!} z;)Ij5!;|RDN#cZ)w55}@qLZ|rleC~?JBdb} zL^)5w?MYZY37;p46HcO^Cy5hI5+|Ib7AJpL3m7;_obWQ5_A;9GGMe@>n)Wi9_A;9G zGMe_XbbdW}8BKc`O`C#^DcG2TjVaief{iKIn1YQd*qDNiDcG2TjVaief{iKIn1YQd z*qDNiDcG2TjVaief{iKIn1YQd*qDNiDcG2TjVaief{iKIn1YQd*qDNiDcG2TjWe)u z1~$%Ugk2BLNT1h)6WE^Fosm`>Pk<*uM;d3O+fMgBy)(qyX97okXJF%uMr1#;0D2$J z8ELX{!wBx^P- zzlV~*;hE$j>C512{MC`?8TD?Xqq{Te-Nx^Nw|V9+=$YUdV(&9V-DhCG8BIprD9-}k3sX&N4;sr9r}PH&US`ALs`)2grW8tD2?QQXjq=nePXv-D0?8AB*22qaGgk|zSm6M^K3K=MQ&c_NTJ5lEg0 zBu@mAN3runAbE5UXxiBAQq4Q)$)vjGo`+i9qs1Ao(BmM&8T-6J%683@38Ip`;2;rf93i63~hdfHb2AseMYTa&(OkW)WY?oTC!9A#BWgR zwcUm7`TLAouhTt$pHb_z?fLtR+O5&^_ZjBzGfB_iXVe0n?)m$STA*#u-)GRq8MJW* zZJbfNQms+Q8RqXZw51v5?=xuT3@vAdmNP@knPL7uqqgBU{}XTa{C!4k!?}3=KBKl_ zyKcnSGtA#-@bwJy_Zj>ph&Y~T@aHh39ybTLbGF&p^50A?8zXBAgCeF1b_F-u%AOI$HaTro>rF-u%A zOI$IlxI(`oqL?M3m}RV-P5yV%zYaR0m{mk!{7cXg#jGL_qOXpD0IrMW5<(xzD=Fqx1;-xuS+8j~S z9PMom9h*bJ=7>D!XkBwC%pBS>hpNmG7tPUf<`|df7?4Iw-XB0mb!%gMqCISqZU~8EvTK?_NsnC?Zkieicmpg ztI>VGpwZLl`B#Be-vXPyPpYDe!y+6O;jjpY zMK~j4PVG$0Ca9D)HA{-Xsun31mI4r_p5e|!RScJnO92ViQ2!};DEW%+C4vTPD zgu@~n7U8f6hebGCK+_h`v;}dv9xR|~3u4l?TjK(nwt%KBplJ)zH2>9_wt%KB!1Dr{ zwm>gl5ZivnGo}TNWk%1K7ErbYlx+cJTR_lVW1qXM~DjjBf!O{iGrmr~DlFHl-|6_hst7 zOx>5M`)j1XM*3@{zef5BapnpU<_Zz!3K8ZC3b{grxk7BYLiD&ol(<5CxI$#OLQJ?q z9JoT%w?e$Pg0iikX)DR1*j`DNK#vY9L~$#`Z!1J@E5vLo=-3L;+6r;n3Q^e#QQ7Nw z@B(GNK$$O4<_nbh0%g8HnJ-Z03zYc+Wxha}FHq(Sl=%W>zCf8TQ05Di`2uCWK$$O4 z<_oCt19%5#u2BS1Lr}n48Nh$I^CDO23*H`J+SLxSR z>DO23*H`J+SJkfcTeT~r`}I||E2I1MRr>W+>7n23etngGeU*NFm41DdetngGeN~#K zC+XK$>DO1KY3GA$j3Cz-L9VG@Yr!?u$mm(mHFW+OI)6=NbBgDW*Yq~y+l1Hg>2-X1 z9iLvur`Pf6b$ogqpI*nO*YW9fe0m+9UdN}`@#%GZdL5r$$EVlv>2-X19iLvur`Pf6 zb$ogqpI*nO*YW9fe0m+9UdN}`@#%GZdV`*RgPwkao_<4KTMKT`({IqzZ_v|k(9>_w z({IqzZ_v|k(9>_w({IqzZ_v|k(9>_w({IqzZ_v|k(9>_w({IqzZ_v|k(9>_w({Iqz zZ_v|k(9>_w)4vVF--h9D!`rvv?K`A@hxG4|{vFb9D!nVXsdOP8xhanf%f2R$-^3#~ zRnrr)Z<79|)Aa^DuQwPEh>e>`uRh&m_30*SN;mP;O?gUhlc$Vl`0X_4o_JGUbNV^I zUpyGC(l_DZCLX*gHk@uHxvBLTW0^Pjzrt_IkH)&6!H+lb<4yTdZa@t zTh#OxHN8bmZ&A}*)btiLy`{EyKDb3qZ&A}*)btiLy+uuLQPW%0^cFR}MNMx}(_4zS z{RY?c7B#&^O>a@tTh#OxHN8bmZ&A}*)btiLy+uuLsm1y|uIVjmdW)LgqNcZ~=`Ct{ zi<)vvX230(!EI`KTQyymZMDBmO>e8FwypNJ>1Euf8E~Jb(BB+y)5~tt%WhMP+w`*A zs)c?fDL;Ji#neR~M zJCykjWxhk1?@;DDl=%)V`3^1l4rRVWneR~MJCykjWxhk1?@;DDl=%*2zC)SsQ06<7 z`3_~iLz(YT<~x-64rRVWneR~M?@{LOQReSalJ8NH@00$0(!Wpo_kWnKH>?HU*BjP? zbw-MHMv8StigiYcbw-MHMhcCG;(48sVmv3+HQl79o78lZnr>3lO=`MHO*g6OCNL1Xme?Y7L0j>HjW9417+qK{>W9417TiaeQ zy31I3m$C9LW941O%Daq}cNr`1GFIMYth~!ud6%*BuIi{asE$UD5qGKMUDeLE_fy?v zth~!ud6%*BuIi<9#>%^lm3J8{?=n`tNj&o=@ywgVGj9^lyh%LsCh^Rh#4~Ra&%8-I z^Ct1ko5V9^y`d{8^Ifd0_sC{-vCMjVS+nUjrTDv8Iq>RMnN`O!tBz&9ia^UY`Wxk7*1FvzFRa!skojK*e-#E%*-oLtp?VUMgdBG{( znNwDqG1EtQ>e}PFZc$PkLugneSrdz$>w3zKfLu@60L7n|_bK zi`BdSXpfAS7O`vDZh>HVr5oh z%k+^l-^I#&H7Ls?e)3trlkZ|>zKfOlE>>pEwyf6W_c$^s)3eISPHg|DK$*4NvRa+( zFOcs46euUZi2Y}vcZQeM8lCQ)Ic2_!mH94KriYgKE>=!@XHJ>#VrBJN)tB#LL#khqC&(ZSTw}tNk0jGpEdYa#?-B zZ}85XvU-GV&t=Md7b|Ne#OeMnR_41{neSp{^%|$sX85{M*4l`F>;Duet2Y@Pah3Tl zR+eta<9rt@^IfdWs&!dC&QJa`PkLugnHB7^dY^5t440)gF28r?l%+OC@60LlU98M^ zu`J5A=DXZt&c0^Z3k;;5GDXS-{UVIlTvmRbn@Ai}4nNwCDx9y!d zW%bsspu(72Va%;C=2jSUD~!1n#@vc}(0Wi|%&n-W*!JwKq84uS?5x6=TVc$tFy>Ym zb1RIw6~^2OV{U~px5AiPVa%;C=2q0A^ft!a3S(}CF}K2)TVc$tFy>Ymb1RIw6~^2O zV{U~px5AiPVa%;kyDIgna#B`RCs&*Zs+^ZnO}tY%Ruk_9e+B$ad51f)g%4u?HuwSl z`hSBT1|K4QFZM^UGuRJ!t|odw&rGX{KCmAg00+S#a2WKr z<|-$JRuf~`ef+7&&eN>8bBQfO5tljv8R6k6ph9d0~V%9H*rCxuoyDYP2;q|mBP z#8R0#DYP2?0=7>It#VRmHB6IoKPeHmPYSJaQfM`N7xoU)eNt$ZlR~RH5zF>2(%*yq zUTmKfS`B{%yBXXKJ^=n-;J*WZ1Ef!J77+Ka>$e}I7Qe$^e;51rus?)N{|f0}A^j_) ze}(ifP71AtkMQL0^Q(_yKZ@Oo{TTMgus@FdIQA3RKjiQer0fSj34RLnSNJL?h3d}t z#6yAZdQPK@TnXikjg#Ar^8=EP`D%<052niB`soH+2_^%%{GgP+2- z=EQ+DCq{GP;AgO{IWd|O2iBaJ(}`nFCyqItI1a2iabV4fbuORLniB`soEXiC(VRH2 z=EMQ*3eAbpoEXiC(VQ5~iP4-G&53mipGt-1#Ar^8=EP`DjON5>PK@Tnp*1H)b7C|n z4y`$HXw8X3Yfg;j#Ar?&T65yiniHcrF`5&jIdN#si9>5n99nZ?G$#(NIdN#si9>5n ztW)@m)|^Nayh33R)PK@TnXikjg#Ar^; z>BMnp&51*6PRw~_acIqnLu*bPT65yiniF$6am?w&u}TOQqK1;x(3~2YQ$urV^5BV}j^@S#_K&8ed~bu_1r=G4)gI+{~QbLwbL9nGnuIdwFrj^@S#_K&8ZXT z)X|(eaZVl0siQe{G^dW{)X|(eno~z}>S#_K&8ed~bu_1r=G4)gI+{~QbLwbL9nGnu zIdwFrj^@S#_K&8ed~bu_1r z=G4)gI+{~QbLwbL9nGnuIdwFrj^@+ zi4a1_<8d_a^L+Zxv%YK3ne#p8+0Xv&@7`yhvxzzL#GH9z&O9+^o;+usm@`kznJ4DV z6LaQ?IrGGvd1B5yF=w8bGf&K!C+5r(bLNRT^TeEaV$M7-HW$P=%LVbl;xSu2c8T=CXW$Q}8b73wR*!cmUV z8Z+5?r&Xx05DPV@A^a{^`#tP)*!l{w%Fko#{Uh0W7Ae%qe4*Yy5^D9hP_rCD&2k7e zCnnU2eW6zD3pFz-)U$8luRzUG%DxEdjY8R%z{{YX!UQoz9;3e2BGgxig__kDYDI@o zbNfQA=nyW!F2P=keG9g}Labl)6=I>jLM+r*h=uwJu~1(j7S@7wU_JOrP`$r?T@5M+ zkgcx}3(=cmk^O2cFGO#OMLM(etYf5P#Ih-H5WTVElTt*;OZZ>L0GA(s6S>?&-1g;*u}3bF8`*!l{w?2lpBVt*XF z4*L_>_1Je}-vzD!SAwg+HQ-v1d-wN3b>{VyG+=MQZp8iz>?Z7Hkank7X{u%h^ z;Cj_#0r9+mcwV3!(#JTS7bu6c?RZ|G9Mb4`UZ5P(z8(elfSQq3NjIn&Y1vQW_p6*? z0Pjb@qo6r2P?R=41L`{-vQL0t1HTSF3w{IC`%pS&1l0T2vR?pS1RbRdlph)$r3;AC z1&Y$Xo>9EKiv1e4W}a34I`;QC!yDlDLCrbq*M9|n4C-lxO2)to;5hh8@Za$`0ZxLK zK}X#JqHY0Ew}7Zypm?jZDbgBCz*|5^*8-wzfugHzeOFVc-H?UaIaKIKTR@~OAkr2n z$8(7zZGpe{F1(8)SGX4R1$v|QK^CF}MOrbh7;EonAg({i=80gw%4} zePw~>w_Q$MXnx!Fzi|xAYku3u{|5Xm_&a=QCST?6z`(oUyixt3c%TOJ{`N7Rsr z8WK^%m?LT!b3_e^s38$GB%+2fx28~|@=>8PZ1UYDh#4iKrnF zHB@eFzmBLO5j9k9Y}*kv)QH<&98p7!xQ&jep+?+BN7Rsr8fwJtBTs;isG;&+qa$jl z5x3E8EhM6b%6n})qJ|oA8y!(YB5FuP4T-2B5j7;DhA~IfPpTQ9| z)cD%yRvZ#hL*=)&9Z^FfYN-6yw%c{6{MP7*8fr9cbVLm`f;Kv$hD6kmh#C@6Ln3NO zL=B0kp+?F&PuvkTB%+2y)R2f85>Z1UYDh#4iKrnFH6)^jMAVRo8WK@M?JT5PAfkpu z)R2f85>Z1UYDh#4iKrnFHHZ1v zG4zp+s38$Gj60%+dM0jPj;J9KHPo!CT7l-VghbSkh#C@6Ln3NOL=B0kArUnU98tr- z5j6}PQ9~kX7&xMaMAVRo8WK@MJzI1+DkY+ZMAVRo8WK@MB5FuP4T-2B5j7;DhD6km zh#C@6Ln3NOL=B0kArUnsqJ~7&kcb)*QA0hW)HUcCrO^>JB%+2IU+6A~s38$GB%+3z z>u|XvYN)vm+m5KA#uqMeL=82*u6UFP~!{Rj;NvLI&3?lhD6j* za~-xFQA5pj_^KRHL(O#<9Z^FfYN)vm+m5KAMixd#)KD`UM&c3?H6)^jMAVRo8WK@M zjShUIBWg%Q4T-2B5j7;DhD6kmh#C@6Ln3NOL=6*;sG;|M4GLo(XBEagsw#|mtW>Dk z2BUU@5NeiK_($?p81uap#(Xb@niKFb{|tT!)Jg`GJPsZN`@nwAa0omMeg%Az^L&?M z&VlDatuD}c-UNRIUIZ^0H7+)41*UKbxD<51P^hflc!$p)*W9@9W1ybF$@W}IVcc^m zh1v~4cM*3T6?!iTp=VSI47Q%1kHwhh?3pKLvuM?c-Kkw@u?03O=V-N$~w-#zNt>c5w*`wC3*nY@o z3%am(b4&`{LrFK-1NMRkz~lC=QH;;)=l~#yv=()^hl4)8GvFdw%8a^v;Wp@#+hqv+hE#!4P^jqfjF$U5`dm zw(kZTz(%kMYzAAvR`AoH=N}3+zi0d`2zv?GOZ*RWnE1cI{~P?D;Qs>u7HsEw9sqZO zU(oeL>R z$UP!*kBHnOBKL^MJtA_Ch}>R$UP#>x%nEL zdqm_O5xGZ1?h%oDMC2Y3xkp6q5s`aD>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!* zkBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^M zJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}>R$UP!*kBHnOBKL^MJtA_Ch}=ml6xe{J(A=eNpg=Qxkr-RBT4R&B=<;?dnCy{lH?vqJqhg#l6n$qbncPV zlTf2`k7UfbM>6KzBN=n=1Lq#e zz_~{h#=N?JTpy~?AJ(A=eNv&3OxpR*sxkr-RBT4R&B=<;aX4S_y_eg5B zs=YY(NRoRb1Lq#ez_~{k6J(A=eNv$3A8Jv401MZI8BT4R&B=<;?dnCy{ zlH?vqa*rgrM^aBAb%um65uBbjjSk<<*o(YZ%5;oKuh?vW(-NNNt>CC)vP z65uBbjjSkxV%ENG6(wP1g|2v)Y z9`#3k!UvVL-sAl>gb#ragU&hcp>MiJeUp#Tekj6jQ2U|C)_y2L*ZV!{n~YxozX<-n z{Q7^ezl5#*P;|^e@CnNMu=|a=FI}hZ%cymOL7UzhctEJtyh1-MZBq;}YCk)n^ZYhN z5~D{kZHgg7!j+)MFKs;2Y*P&JF@C1m=Kbu1ex})`7-IA@%{F318&3?|6f0cfr-W@h zA8g}!UmH*Q+IYs-rdXk06)TK>a@VFelRk}p4%NmJs5a@-wx2q+NuNeP zX=;-`jaFS7s%t}aZK&=uemf)hjCdBxyHW3(2OFiXA)%iuZIrskgg(zkWi>{v(h*wQ z8{?nHen9oO5%q42cTnC*xs|*z-eXiP>ujoJqqV&ycDJ5SZHavv{7mdV*&D&X1~-AP z7~>T_CSD1Cijo}odt-2?%Y#pXp9MD?6QB35iGRZWqVQgMyifRP&>ru_xud*#vg7lm74cq&Je^)^mf<>TK45~zH1%+C-Bh<=3 z;rl7MRW^Hm39aY9RX#i>{3&?d2q)~`C3`0&KQ!uW##@EkRgXi$$f){KiE7H|Cz#vS z{~BMVyRKR2cY=hTmuQdwQfF@WyF5a@r7Luv(C)X) zf_7cAj@LCC-FLM6T^ONfN85wPz^6dZGqlsQw+Aoq-xtBN{OX>)-EWx*wL(?+9m>5n zquuYD2=$h(@Cx>Cz_&SrXPeuDcR@$U_C$eyO%#HjRcNPAZ>Jysyx*S+KCkS^Xf=Lb zd699#sI11=1?~a6!5**|JODlqo(8`Oej9uZd>yoMKCcYKI1SE#^G1y_jEg|`5uev} z8gCKqP>nnwbicMkD(Vv+13izlgKOR)ExG(v&|2ETUF=XD$yV*?NY##UJ0%bKNablm zLig7@0{3w{f_`ui^lF?P%FSHvd~63w+d)3IgM4g`*>t z+iPrgNP$MPvBTff7EXe{r`&ApNF=}_d-NNB!uMdClO1ZOIs;nW2{SukW~augW5G_1 zQjO!Fb-NSY?$n6Y<$gl36W#9A=+z~^1+C$ou(T7Fc4{=LUs3W-#-Tek4t0rDy%SaM z)R@%vK5##1o$u7h)M%aW)cDl)H$cy%?Ud$S@*-%p?-XP9{%z1|-|6=ag+Ha_SJ>A; zN1mM;nHsJ6oq;vK6V2~b9xGd8RsE__s&TQ}<4$SG_+Cmpd$vOfZ==&A!O@za=&F-g+KH|@ z(N(8->(jrit4?&)NfhlwSDompQ?nmFvvt*}84sg%)rqb;(N!n9>O@za=&BQ4b)u_I zbk&KjI*F*A=<4sp@YUe&#O>AKAF%%c`$4jo2kB2Ar1yM~jN(D50_!NHbTqon1UcAN>%0^h277(!badsxDE z!FeP7-NW>E537z`qW7?b%Y|L=-v$3&YVRr`d+buHxBZOH+(q`-C01>p1f4y0iD8#G zd+Z{6?DAK+WPb~E_SogGatWP1cBvMO&K|p{>n`fLi|nzB?6HgNu}cv{=RpHqXrL=_ zzuXl#d+buIFuH!b&_);9=puXUQk3woTnX7@7ujPM*<%;kV;9+DmulJPbidH0IY6Vc z$1bwRuE5!2SK#ci%U|UZ=0InUU1X14WRG2FvI|Xikv(>iJ$8{jc9A`HNg?_I0t(rM zLUy5$T_|K13fV;-wF`ypLLs{pEA%fEvI~XmLLs|Q$SxGJE3iU#p^#lDWS3gE|7C^j zLLs|Q$SxGJ3x(`LA-mLybtDSeg+g|rkX+U`kJe3x2)aLfNl54yNR5;iI%%{*Di7YyW3xL6}lJRtvO_$ zOT9ln_qEiONI6FL$h(!5=@_X<*CQ3_NM&d)*~PDWu-z~3){K+O-8=8rypwIm z(%nHX_5sj6^=^O7Rj9AI3a$3tMAzM#iL&j!dpEt$Zu*_w>UUhCuel0e$Nnz1=LvU9 zb-pTRIJ=pJ-YwPnYJUkj>h4w^=rcR^?p8Kv+wp3*W~FR94)3PV+Rgm)Zes6l=AU;H zfp<%L@+Ixbm$F3ti#WWS2)tW5^sl$-*GFjekI?ELAwoVvgnWbu`3P#KuR6 zijNTS9wFAHP(=z=q)OANqona_Or=t0ILeQm7&&ze6gqDpIH-g(_00 zB84has3L_bQm7(@DpIH-g(_00B84has3L_bQm7(@DpIH-g(_00A{AH_DSFiusz{-V z6sky}iWI6yX-?8dS`{f&kwO(IRFOgzDO8a{6)9AaLKP`gkwO(IRFP6|JF4?o6)9Aa zLKP`gkwO(IRFR@DPN9kvsz{-V6sky}iWI6yp^6l$NTG@psz{-V6sky}iWI6yp^6l$ zNTG@ps(2JtJc=qFMHP>tibqk!qp0FhRPiXPcobDUiYgvO6?-_t9?r0bGwk6EdpN@$ z&aj6w?BNW1IKv*!u!l2v_t>GpyT=MS!(Ps?mow!wHRrbp|hN9(3X>!wHR4&0-4)1!6Mqjl4x zbbnP)H97=|LeqD5M94^q`O)6w-r2dQeCY3h6;1Jt(9H zh4i419u(4pLV8e04+`l)Aw4Lh2Zi*YkRBA$gF<>xNDm6>K_NXTqz8rcppYIE(t|>J zP)H97=|LeqD5M94^q`O)6w-r2dQeCY3h5!|=|LeqD5M94^q`O)6w-r2dQeCY3h6;1 zJt(9Hh4i419u(4pLV8e04+`l)Aw4K$KML88LiVGO{U~HV3fYfB_M?#fC}ckh*^ff@ zqmcb5WIqbok3#mNko_oRKML88LiVGO{U~HV3fYfB_M?#fC}ckh*^ff@qmcb5WIqbo zk3!f3I$#gzpcjSoqL5w`(u+cRQAjTe=|v&ED5MvK^rDbn6w-@AdQnI(3h6~5y(pv? zh4i8jcA5^@X;$$p%jF|rzt>!UW&11y;$B6ll5%V7-<{x0z?f|oP z2jXY+-vi8493X!eG#$wL3sRet>@b0R8v@ zdhi2Mmw%lCJ!^MBeX-H=2?v<9JHV{n0qM#me*oSh{F1+j9(>7PL=V2iuV3QVFVjZ8 zOdI(!%KtLT_fFhHfp_8-N{3^@W1#1XAD5zxuTt_0&@+3F>kKN_8H}DQeq5Rv6?(4t zap}azc&6oXsl~r~uK00j#=m;5_;IPlB`<@XD}G#>F?z1}an-d@_1h=(T=Cv&zW@o#;ez_V%xnf*A( zT*pD;z(HNP{-tX+dan4O<~NKU2OZQkyWDfd2UT}Q&z>Dr-evTd=%8xQdWXEvnRX<( zPtXRRpbb93ti=<|T0EgPsQ;?f=t#9b+qcT@LwkK_uaElbBR=;LpZln%2azv^izEG{qd)M|*nagy;!v^I$8=Ki_x$>g z*nZaEPjv0q*ve;cjP2Lh%C;kIzs6R!9dG+JwzBQ0+fUT(*VxJ>ezM=M$e~)$SI%sI z1@xR)fACe%vwZ#f%9-&Qjyw*2of6Oc^#>>|K7)IxevJ)XzRb*MglPNypku`$ zwYyQF=RXfAni)NQKctvu+p{`{;+{`CB%K=_T@Nv4KO}wX81?4HB)HYTN>?uNT+JcI z0uA6hxLCm;7gRdhdr#U%xCx}w)@$`WF3d;Z4XOPKE{3SVRDSa zWLAe&n>sW3)nV1C?PZ{Q;jeIyU*R6V!qt9-tNjWZ_zD_e=lbADauW8hm+joi``3>O zeb?T_en{xMW-oi;|Bn5M@L|Pp_O%zfy|b^q&~2Q3?S;;%o`eT>x0mgf_#|vRsouf1 zdus1=Z+y*u>93zuyR+?H`$;k2U)?&`^4E$44rt!B%#XaLLP+u~ay${s);$;65cnbUm=y~|3=+U0iwb}j^cn$Pyz*ADA z(etZMNt4DT=$!B=_njH9PGTx`jc%LTQf0}InX|npK$?Bg*15Z=? zU-gav!2o^V0JS+lA2&d44p5r|)aC%SIY4a=kQEP5n*-G505N=k+8iKm4^W!}#OeWR zbAZ|$AWt5kHV3H90cvxA+8m%Z2dK>fYIA_v9H2G_sLcUtbATu}Ky40Cn*-G50Q?M4 zn*-G55o+@YwRwcvJfaA5H8?_Ma)jDELTw(QHjhx7M-)$V47GVg@x-=k^N8Y!(Y1Mm z{NxC=d4$?LLTw&VZ1JzI%_G$25o+@YwRwcvJi^r;;cAain@6b4qtwMwYT+ogaFp@L zQO1Bri6lqi|0rX+qcDFI=8wYsQJ6mp^G9L+D4ZXK^P`O8juJ7BGMYQ8>mLh_it|39 zpQ;~aGde~dVPj5vRcD?diGKSs1aMw~xJoF9b$LHHkp|3Ua4g#SUVc@X{w;eQbR2jPDZ z{s-ZI5dH_@e-Qo$;eQbR2f6Y=_#fo@2jPDZ{s-ZIkh>U!|3Ua4g#SVKALK3u;eQbR z2jPDZ{s-ZI5dPWAK42Gnp?lb8;Qtx!g^yY9e#DxeTFM%r+C@dDDm@%XW;)CuACj=1NMR!dMyDvzX!+R|2X^~hyUa7 ze;odgbIr%$|2X^~hyUa7e;odg!~b#kKMw!L;r}@NABX?rT={YMKMw!L;r}@NABX?r z+{JPDKMw!L;r}@NALlNP!~b#kKMw!L;r}@NABX=F=>G)zKLP(I;Qs{oasvIIfd3Qd z{{;M>fd3Qle**oVfd3Qle**s5Yd&C?d7=3~f&STFUbgd`6Yzfm{hxq;c9{=Op#Kx- z{{;M>K>uH(7x)_U3}54pzQ!GWow4568S8zW5!}}q!Fh-GzQ8-Yj|n}VdY17N`@GBc zcVhj*jL zQ_sddp7P%A{;$VV-r?OP9#46PciSFMd53q~9#46nciSFMJsbCU$~(O4Y>cP8!@F&d zr@X_v(c>xa@a`i$p7P%AwmqKm-tIoe<05F^a(9WxQ_nJ<@_z2NJ)UAeccI5q-p}17&U>F_JoRkg@sxLUcgYaw z@f5qd3q77w2DJob_DXD;1y9IP1@a z-%>q3r*W1`ej#R_BceVRzhql6O8-@iGCt%Zl@C84^cQTN(>P22Qby_{hkZ8XqPEkN zXTX=hmnnaRGkBc!oO%tP%~{iP(&wnqvG+OY)3$rS=hTDv7-vw=slTx8eCavm-twi| zmoH`Dw*LUzs}P@4zB&|~)V)6-^!m(`y01Q=S2eaY5+sa*GE{9Bg?p6xuzZ0AX4 zJ5TDqe5B_&PX>;$Ct1gJGVl!NN&3E%T>nX~{3O?WlB+$*b)M7}>ioJkqh~CiS1pVQ zkAWWNKF{p&^Ncc{XO!_g^TW@JPyNb><9S9L&od|dJmZe%8FxI-tnVrMlvDI6r zrTf)>9?Tz}ihHK(lsRJOPSJi(i3gW>)zc~Qa5XqhesY?g>oh&rY4VfP z)X`~T^=TsTX>yX&wqCMP*fPI8(WIZch6CgPnY)}5wCPLqM0CIdN5 z26CD@I!*3zn%v_w@#Hk|Vzn;|`rWYPoFYIG}40=WGu;P!8{2BHbsQn#O;+f}R z^}M?Gi`MVItnJ`e@tKzUDk_d(LxMG2CbKOv|t$xoyvR z4ig)P6-ms=i=bQCuv(c*JPSH3^%@4)ln1SpANV^jzq$dLP@K z`59IpWZQG0!-@dDe!mGdtO#IqZ$9k(9fSc`;3J6!!)kH*ulg^eBk-_#G2>#6^z)rz z_2$MUzAx|ZAoR@Au=+S3=?Fipp3b&cRSm1Z+Z&9~n~%_&kIsy%}40XN9fH*=*>sSDo5zeN9fH*=*>sy%}40XN9fH*=*>sy%}40X zN9fH*=*>sy%}40XN9fH*=*>sy%}40XN9fH*=*>sy%}40XN9fJd#G*7&C`}YfGcHIo zB1khLNGl2r1!>}HnkbZJERc?$qugVGG-H9ZnCX-4d@rrY<8tSF>A3U%w77D)^ZzvY ze_Fh`#QA@k{68%YUGgUA%s;I-WAD!V(`5c>MHt)8{L|$8X~mW?*}vgm&ivD4{%P^= zv;B@UIP*`F`KQVJ(`5c>GXFH0e_A!NH%Jpt(y9?1PoAG9o}|h1)8zSS^87S;ewsW# zO`e}tp06vRmr1K0eFo2?rd6A^9X-;jQ`?RnY1OQ4M~^hUPg=F?66g78^87S;ewsW# zO>Uniw@;JXr^)KmiWolLS$&#_k(N$;9!HF{)MDGSvS~#FqjUJQ;(+b%g3j2}WbA1& z_B0uLnv6ZIw(lc7YD<%`r}f6YOPsf-1Lt^YviEf0v0GZ2v`1$MX}x#v674P_bRUr> zpHGv|r|Cn}Qm>D9Oh`+^wjC4FQnKxN|BFmMO(vgKdv{6XU)A1iC$XKqr|E6eWbbLR z_cYmin)aSnEAYQO1C~}>uP6bri?pd1X;UxKre35?ouM6_VFv6Bt>z4^ z<_xXoj55`+;0&rhqbyW5>N>-7kTX07IfH)Apqw*k<_u~%gHFz%lQYV}{9k8WXQ<^f z%CBs{3_5!h%ZvnHW+eCu$G^hyuW;jBvG|Fy(#|XB4iqYbzx;U7~a93_7RL&vUhkA3Ftl#ndP@t}NAOrmoe$sYg)s z1-)Wwl-eKF?6l8dK1VgrVB4&YYCgfXxgBNPI?A|plyU2*W*GddxgFIgTQ&@gYOHPB zvrMCmxJOaKtGf5T;8oqbkh^9mzn}G*co6E!jqeeDhg$m%we}rq z?K{-k>zwCx&ht9wd7bmT&Us$vJg;+}*E!F3InQ@F&v!Y`cR9~FTKYNK_&M76IkoYz z;2cjG&Z(AV)4I>`l;Irh`W)^09PRoX?fM+;`W)^094-1BE&3c!8P2I5eV%WDo-aDb z$mkqnqH{cDIHx*wxyLN$Xv^nl%jZ<5E}1tn(m%&Y{~R@YjygR@>pn+3d_%2!EOV(}eJ^jQbsPPZ=MA-Pqo4A;q1J8O2l{=MH`Ka~e#-WSTDQ@6@rHD0bS!#< zDD(zb{)Sq*ORj-_%JYU=y3tquhFZEY3Hm9|8*1HS!FgKWd0O9jwcPuH^VIBlYT-Ps z@4S>bs&Zfdc_~viZS6d5?Yzd_S5@K`cV2qXF~K90q_7{wehfUpf33Ik(y-6t)fDHY zWS_xnD$YyKw*BAoTnw8=ibjV-*sN~ zrE@atbzZe*d%5uY+}HQ<@_o+#ea`TG{`&)>*$;?jKcL2cK#l(pJ^v6r{}4U@5Iz5h zL2uV~+nZ$N!Auf5!1YX|*|u&k(C#kK?k=dlT<&&v zfp>c^@NVw~)t$?&+Y7wgdqFiQkMMIrHE7$h^nzlkjwG`E9L9bQV?T$npTpQVjE%$C zIE;Rq!6Tvy~2cXA*6Z9Gr%H;j4G5LN1|@ODN1hNpb0F za0!K6LLrw>$R!kV358rH54=nsc$qx#GLiW*wS1Xqe3?A(GPQP@Jn(X`M{Hjv54=ns zc$qx#GI`)-^1#dFftRVN%S6}9)YoOA>t&+rWuoh4>g%%Z#piS$c$qx#GI`)-YUDC8 z_A+_kW%9tw#MsM3*URLAm&pUKkOy8N54=JicqRU(&UuAeN zOTR`-zlNV*!_O36rtmUF9GD^wOc4jBhyzo^fhpp^6mejRI50&Vm?92L5eKG-15+qu zia0Pu9GD^wOc4jBhyzpH(G+(yMI4wS4ondTrcl%rcRIzLP7w#Dhyzo^fhpp^6bwwk zz!Y&{ia0QZx~9<86mejRI50&Vm_k=m#DOW|z!Y&{ia0Pu9GD^wOc4jBhyzo^fhkls zMI4wS4ot!P6wFT%2d0PvQ^bKO;=mMf;2Je@jT*T|9JodtxJDefMjW_C9JodtxJDef zM%`Vb?yeCBt`P^W5eKdj2d)tZt`P^W5eKdj2d)tZt`P^W5eKdj2d)tZt`P^W5eKdj z2d)tZt`P^W5eKGG$TSL>Mj_KEWEzD`qmXG7GL1r}QOGn3nMNVgC}bLiOrwx#6f%uM zrcuZ=3YkVB(Mj_KE zWEzD`qmXG7GL1r}QOGn3nMNVgC}bLiOrwx#6f%uMrcuZ=3YkVB(Cls3YkG6Gbm&Rh0LIk85A;u zLS|6N3<{Y+Au}js28GO^kQo#*gFCls3YkG6Gbm&Rh0LIk85A;uLS|6N3<{Y+Au}js28GO^kQ*rE z1`4@>LT;dt8z|%k3b}zoZlI7GDC7nTxq(7%ppY9VLT;dt z8z|%k3b}zoZlI7GDC7nTxq(7%ppY9VGK)fHQOGO`nMEP9 zC}b9e%%YH46f%oKW>Ls23YkSAvnXU1h0LOmSrjshLS|9OEDD)LA+soC7KO~BkXaNm zi$Z2m$Sew(MIo~&WEO?YqL5h>GK)fHQOGO`nMEP9C}b9e%%YH46f%oKW>Ls23YkSA zvnXU1h0LOmSrjshLS|9OEDD)LA+soC7KO~BkXaOR6NTJFAvaOTO%!qyh1^6TH&Mt< z6mk=V+(aQaQOHdcaubEzL?Jg($W0V-6NTJFAvaOTO%!qyh1^6TH&Mt<6mk=V+(aQa zQOHdcaubEzL?Lrh$lhR13K1&vyejnCj5(>|0pSq#FzC6dxwyZ4GN+7mRQNq?uXUUw z$D5M|Y+jE9<%6?t$nZr5dz_y(?&M6bN?Ju9qkwebuS(ttKdpL8- zja}~9#W`ijwmru@7Z1kGXIc3PUz2-74NIjPR* z*~mF%(LS^1B=PKu_3PWT`nPHIZ>w#N1#hcfjQ038ZS!r~=G)@aC7!2!TW2=jD$JsaEUL(& ziY%(gqKYi4$SOYc1zC+#t_rP+EUL(&imdz&sl;c_qKYi4$fAlYs>q^>EUL)zJ)A76 z$fAlYs>q^>EUL(&iY%(gqKYi4$fAlYs>q^>EUL&dg2q^>EUL(&iY%(gqKYi4$fAlYs>q^>EUL(&iY%(gqKYi4$fAlYs>q^>EUL(&iY%(g zqKYi4$fAlYs>q^>EUL(&iY%(gqKYi4$fAlYs>q^>EUL(&iY%&l2UWa-D&9dA@1Tlz zP{li_;vH1+4yt$uRlI{L-a!>PRFOj!IaHBD6**LqLlrqxkwXocTvT=sKWa`?+x;->h$i7rk(V~cbfn){&r2ag!t;tJc~*7ibtOKJS9Rv;N%Qf4<#?~^%*VYd zFCX`ud0toRBfY9KANLBqycFesc~xg#>p+Z-#(DL{_Tp8Yc`3~$o*~S~y<#UX)fv62 zGta8dy!vP#=~bQixL0-N<8N`iS9Rv&Ue%eGN_`%$^vg@7w!Nw|FZPUH)tT4I5TjRh z=CwY=wpVrLS=E_mRcD@6o!%*1|3c4s=~-uERcD^ro;<5M^Q`L3qwu_H#K(7Xw!a6x zsxzCm}t(5QcJc9iw=$WFtT7k>EvAwD@&#X~it-y9KExNS%B!vU3|`flS6j2~+1fm-I`g! zys9&=RVc=vf@p@8n5QM?X^DBYM4!hqy?Iu3=2_L5XH{pORh@Ze#`0>XK608Py{a?M zELmRd)V7~o=arlJUc9O^uiVV&Rh@aQLNR((XP!JQPo9>iUFX%Vbq3mXUhUfUVvh8x z&OB{Aua>C$VpV6JIk&u8x{vg#&b->YZRZAgwbs1}@4en9)H5TYGKxe@ZEaMjnS9|- zvHuNQ?`WvxO;9T_WNRgcQ156YVqVoL)H@o&1)$#1kge5d!mU11`t*@{6IrM=8$zww z5NgeaP-`}XTC*Y4nhl}e(GY5#hEVTl2(N>BMk z1b3Ipx{{{ijf|NT@fzgumgxTK_3qZwv|b=9lny*jiO6dj?x?e#xH2 z)|+3l_2yS1L2V|e%>=cXP%P5FsLh0GQ)lz)HQ_e<_3Aa@4s)nl_K}^G=*=(Ldh<)D zH@}36LPEXyB~;`Q>dh~qB9BmSehIZARH!$u#T=pD{1R$Ks8CWt2l7>*x zMyO~b)T&XTMgc;N0)!d`2sH{2D%uFqhN6wnrj@`#z4;|X4~{mn(SV|jdD99~q2Bxw z>dh~qqK)uBK5-QFJHDVHKrKnJEehC$4go-K&H3R?4YukhcE_YNB z>Ps5J$j2+H*w%VZ;bMMuOh_oIxMT^x>di0Nw^06G%Jn4;mHZ*L){e^7n_r0qYImc; zVk7Znfpa|BjwcJ8;|Vn$6ly#u)JRaMwI4#qlLgY7F$rqiC)?3ufipLu#&^PfpvH8v zwI)QUQJYZXHKC)&0%uS{jkAOr?+7)vN-S`WB-BVs=;*P)8Ie$HKZK4R3yBg7y$(UP zqrpO=!9wD|Lgf!G(W-3WCEK)xgI=pa-naUy(6PNhbzyXDFVGzs9pMX9BSNBg0dc#4xa~crUGBJDAm)vZ+Xck!0<{#| zdQK|T6H=jLxOa{=I);1aXrrEgCA@RA(UH7>t1aMa3y9|h#Pg842&sjTS_oAOV~NnS zPeRQnBtrNPJ)0!kaVCWM5avUe4`Dup`4G-SI1fF8q~kTl7jjNrzwOtg=g_%?@F$dL z>@3@Chp-*OcIcTRmCPH}vW$yBx2BLg3gJKWQ?NuK{1?K1A^aD@zjwp*ujaoH{tMy1 z5dI6{zYzWl;lB|63*o;I{tMy15dI6{zYzWl;lB|63*o;I{tMy15dOUr3r1?YJ?n4)8{?Pb)(5hIZSwxi(ffs2m(YE98BF`ua&HN(ID+kiJ9n-JylY|ZLEann3;N8TG zzH9FwW^^BvRK9A|`bputpzkQjy(GB{_7PKwa#5kLxrl2n;+l)lOc9zXLNi5ZrU=ax zp_w8yQ-o%U)UI^~%_uvluoO!^2`2Sj@dI=B^iW zzl*uA#b{yO9v10fshM!`XDTbM1 zm??&nVmK*AW5sB!7>yO9v0^k4 zOJHdU{49ZuCGfBW29|K|OStPL-0u?ZYY7@#g2tAhu_fHm67FRQcd-PGEkR>TxaJbB zxrA#jK{F+2rUcEDpqUahQ-Wqn&`b%MDM2$OXr_ewE#ZDkxYH8uw1hh?;T}u4#}YJC zf@Vt4ObMDPK{F+2rUV{J&`b$zl%SasI4MChC1|Du&6L1W37RQ^s}eL*0%Ij;rUc$f z&`b&Jm7tjtI4nUkC1|Du&6J>-61XivGbL!I1kIG7nGzT-K{F-rT!LmwV7mm(l%Sas zG*g0RO3+LR{4a(7rSQKL4wu5=QZ%y^CYQqGQkYzdX0%VcV#QMUTnbl9VQDG+EQO7w z@URpHmU8b)x$C9e?^5n-DVkY|W|pFvrQFd{?qw-=u@ucLMKepe=36wP8A{xu5sgp^ zxhg!VUgj1l#OUnt7SE0fJ%+kPHLhb+%f=M=B*zScdZ$3;dZ$3>8HQU_N5%`3I2*r3 zHDbK%ahnyMIEE{ zii!7%0b?QPY~;Pv-7RpCzmr1cYvub}Vu^h!NN3qLM>~a*l9K|k2 zvCC2HaumB9#V$v&%Terd6uTV7E=RG;QS5RQyBx(XN3qLM>~a*l9K|k2vCC2HaumB9 z#V$v&%Terd6uTV7E=RHN<9go5ncv5m-^V%M$A8~XKl^_A+4s|0-%nlNsyn@!xK(#5 z)b$(P&)%l;2ZWk|6y7dQZj0RkYNt`zpTNEo)J~%+(N3enmEbDPY24g;Sz8us9lLwayxjJ zug5!$3Ri-E#xa_SRf%R|g&sBE=AA}`dLuxnr>?@k@sZwXRM-GEf=ysE*aEhKp9Vhz z{x$en@ITMf?(-)e05xwf`wQ~&0r>v_{C@!cKLG!w@Lvl5rSM-0|E1pPHBk!xrQYdP zw)roG|5ErbjhX*a_%DV3(wO-#^-ixs^Ir=8rQYdPw)roG|5Erbh5yo+`7e!`|I(QG zFO8Z1(wO-#h5u6cFNOb7@ARs2^Ir=8rQYdPw)roG|I)bmFO8f3Qur^0|5Erbh5u6c zFNOb7_%DV3(uDah^-ixs^Iw`U|D_4@Uz#xgr3v$2>YZMN=D##y{!0_)zZCvUz0<2~ z^Z!Bk{~-K-5dJ?1|7GxB2LEO7Uk3kW@LvZ1W$<4H|7GxB2LEO7Uk3kW@LvZ1W$<4H z|7GxB2LEO7Uk3kW@LvZ1W$<4H|7GxB2LEO7Uk3kW@LvZ1W$<4H|7GxB2LEO7Uk3kW z@LvZ1W$<4H|7GxB2LEO7Uk3kW@LvZ1W$<4H|7GxB2LEO7Uk3kW@LvZ1W$<4H|7GxB z2LEO7Uk3jlg8vV}|A*lJL-1b?|K;#s4*%uwUk?A}@Lvx9Uj_eF@LvW0 zRq$U0|5fl`1^-p>Uj_eF@LvW0Rq$U0|5fl`1^-p>Uj_eF@LvW0Rq$U0|5fl`1^-p> zUj_eF@LvW0Rq$U0|5fl`1^-p>Uj_eF@LvW0Rq$U0|5fl`1^-p>Uj_eF@LvW0Rq$U0 z|5fl`1^-p>Uj_eF@LvW0Rq$U0|5fl`1^-p>e+T^E0snWv{~hpO4gb~fUk(4&@Lvu8 z)$m^p|JCqc4gb~fUk(4&@Lvu8)$m^p|JCqc4gb~fUk(4&@Lvu8)$m^p|JCqc4gb~f zUk(4&@Lvu8)$m^p|JCqc4gb~fUk(4&@Lvu8)$m^p|JCqc4gb~fUk(4&@Lvu8)$m^p z|JCqc4gb~fUk(4&@Lvu8)$m^p|JCqc4gb~fUk(4&@c&Wx|0w)_6#hR7|26Pm1OGMf zUjzR&@LvP}HSk{p|26Pm1OGMfUjzR&@LvP}HSk{p|26Pm1OGMfUjzR&@LvP}HSk{p z|26Pm1OGMfUjzR&@LvP}HSk{p|26Pm1OGMfUjzR&@LvP}HSk{p|26Pm1OGMfUjzR& z@LvP}HSk{p|26Pm1OGMfUjzR&@LvP}HSk{p|26Pm1OGMfUjzRiga41g|Ht6}WAI-K z|F!U63;(t7Ukm@W@Lvo6weVjH|F!U63;(t7Ukm@W@Lvo6weVjH|F!U63;(t7Ukm@W z@Lvo6weVjH|F!U63;(t7Ukm@W@Lvo6weVjH|F!U63;(t7Ukm@W@Lvo6weVjH|F!U6 z3;(t7Ukm@W@Lvo6weVjH|F!U63;(t7Ukm@W@Lvo6weVjH|F!U63;(t7|8e;LIQ)Mc z{yz@?b?{#Y|8?+R2mf{OUkCqn@Lvc2b?{#Y|8?+R2mf{OUkCqn@Lvc2b?{#Y|8?+R z2mf{OUkCqn@Lvc2b?{#Y|8?+R2mf{OUkCqn@Lvc2b?{#Y|8?+R2mf{OUkCqn@Lvc2 zb?{#Y|8?+R2mf{OUkCqn@Lvc2b?{#Y|8?+R2mf{OUkCqn@Lvc2b?{#Y|8?+R2mhad z|4+dGC*c1R@Lv!A_3&R0|Ml=+5C8S>Ul0HF@Lv!A_3&R0|Ml=+5C8S>Ul0HF@Lv!A z_3&R0|Ml=+5C8S>Ul0HF@Lv!A_3&R0|Ml=+5C8S>Ul0HF@Lv!A_3&R0|Ml=+5C8S> zUl0HF@Lv!A_3&R0|Ml=+5C8S>Ul0HF@Lv!A_3&R0|Ml=+5C8S>Ul0HF@Lv!A_3&R0 z|Ml>HC;Z#8-oBz#QeCf4d7Wcj4u(#OGD=DSWNK*9v^Cz}E_Vt%%vz3Vf}I+1Cnut-#lc zxP7g_*NV7(t%%##inx8Pz}E_Vt-#kG;cF$nR^n?VzE_*#pvwfI_#ueJDEi?6l#T8po>_*#pvwfI_#ueJDEi?2V$*E)Qy!`C`| zt;5$ke67RRI()6e*E)Qy!`C`|t;5$ke67RRI()6e*E)RN9rN>ryJLR7aChv(((2uc zW23@9l7{bA95engv)BGz`bBMxDV7@Jo@$9*sp?KL3Fp`lFqNV zWW3AAC@vZC75`&wyu|+t_Mh@EKTWt>@yh6@26ro72^Fu5egbkgPeASt+I)QCHn0>d z1Ixh*uoA2StHBzu7OVs7!FHct@ye+04GO=YD_>9TtfzL?Q#eu zSx@b(r*_s;JL{>P_0-OKYG*yQv!2>nPwg~NI}OxM1GUpY?KDt34b)BpwbP)!=4zsW z+G&Wnb{eRi25P4v=Gtk9xpo?2uAK(;H9p?8(-3p*G{jsx4b)BpwbMZDG*CMY)J_An z(-3#pQP)XoNKX9Kmff!f(X?QEcSHc&eosGSYe&IW2{1GUpg?KDz5jnqyfwbMxLG*UZ_ z)J`L{(@5*P9wF`NbNLIJB`#%Bel~=?KDz5jnqyfwbMxLG*UZ_)J`L{(@5*P9wF`NbNLIJB`#%Bel~=?KDz5jnqyfwbMxLG*UZ_)J`L{(@5*P9wF` zNbNLIJB`#%Bel~=?KDz5jnqyfwbKM|P4LzPZ%y#l1aD37)&y@&@YV!xP4LzPZ%y#l z1aD37)&y@&@YV!xP4LzPZ%y#l1aD37)&y@&@YV!xP4LzPZ%y#l1aD37)&y@&@YV!x zP4LzPZ%y#l1aD37)&y@&@YV!xP4LzPZ%y#l1aD37)&y@&@YV!xP4LzPZ%y#l3~$Zw z)(mgW@YW1(&G6O?Z_V)53~$Zw)(mgW@YW1(&G6O?Z_V)53~$Zw)(mgW@YW1(&G6O? zZ_V)53~$Zw)(mgW@YW1(&G6O?Z_V)53~$Zw)(mgW@YW1(&G6O?Z_V)53~$Zw)(mgW z@YW1(&G6O?Z_V)53~$Zw)(mgW@YVuvE%4R?Z!PfF0&gww)&g%W@YVuvE%4R?Z!PfF z0&gww)&g%W@YVuvE%4R?Z!PfF0&gww)&g%W@YVuvE%4R?Z!PfF0&gww)&g%W@YVuv zE%4R?Z!PfF0&gww)&g%W@YVuvE%4R?Z!PfF0&gww)&g%W@YVuvE%4R?Z!PfF3U96O z)(UT}@YV`%t?{jw3U96O)(UT}@YV`%t?{jw3U96O)(UT}@YV`%t?{jw3U96O)(UT}@YV`%t?{jw3U96O)(UT}@YV`%t?{jw3U96O)(UT} z@YV`%t?{jw3U96O)(UT}@YWW)JNB1}w%Dh^&&2MNy%GFta1;27F<#+g;+5d1 zD9M4pHwJgQJoqH|S#Yy4@p=E6_$TZy3OC|$BOW)#>~SL=H^%I7W6T~m#_Vw;9yj7~ zW85A$#_e%q+#WaLaU&i#2KKlyu*Z#f+=$1G347dx$4z+LgvU*I+=RzXc-(}?O?cdd z$4z+LgvU*I+=RzXc-(}?O?cdd$4z+LgvZTz+>FP~c-)M~&3N35$IW=$jK|G*+>FP~ zc-)M~&3N35$IW=$jK|G*+>FP~c-(@=EqL65$1Ql=g2yd*+=9m~c-(@=EqL65$1Ql= zg2yd*+=9m~c-(@=EqL65$Iq$7jU_&(7H9mha+}YoH5v8IMxov@7y1pR&Ty&nE^ zYDdOb!S5K=E`(CP&Lia;+gu{$8%x15upF!aE5RzT8ms|p!8)*Bc%PWLPxxujdb-tL2$`(WliF{2VOWBe?**$6ZDi5c5p6yA@=`|)@`b#Xr) z@5kf)c)TBv_v7(?Jl>DT`|)@`9`DEF{dl||kN2xCbbdVEkH`D*xD}6E@wgR_Tk*IR zk6ZD$6^~o-xD}6E@wgR_Tk*IRk6ZD$6^~o-xD}6E@wgR_+wiyzkK6FL4UgOKxDAin z@VE_++wiyzkK6FL4UgOKxDAin@VE_++wiyzkK6FL9go}bxE+t%@wgq2+wr&^kK6IM z9go}bxE+t%@wgq2+wr&^kK6IM9go}bxE+t}Quy9PyA*ExP)yHbq;uQ1OQr41t+g|& z*3PV2du*Ln-?hj78~A77pM&c;{=aK1)*fpH|B~_+?0c|VvHwbA!}eGkwpU`bt4-PC zqu?HJFW3$41HEdfomsnfX6@RUwQFbAuAN!Cc4qC`V_(JB0H`-l^{=C#z5*(H5PSyI z7dusQ0{j}N_fl2zEcgv@7#so9;0xf3pjU>s$GqmPJ?0f??J=*SZ&w8H9gT9#tJr>j zq+PwL%U{R#x~BHn_prUXsXg`vw%0hd$F%c^&?{})V}5I_J*Ib5g?dL-=(on&V|qtb zs5hF0+9yKzOVBHG+GGC?dVNlN%x?s=GfUYXo5a2ZUIyRsHOC7;zi-tZF9N-isy*&E zL))3pY>)fR&~|1u+v6qJUfa_izXjVX<=W%#18;LJ$IHNKN@~Dbunw#TKMAhlJgdPq z;GdeSIC_htH|9v&s%x;sY*G z)V2LV>@w^RVV7f9fVWdpiTx4mD(pM3tFb?dU4#8G>{{%PW7lDS0=pjjPVBqD72ry6 z6}Sdm3v%zw^tLC~Q{wez?THQ8UiH+T_zP^WeQIa!w>?3-V+OcALAzrfxIOV#9O>0i z?f-vuXCB^Eu|EDYOVTB6DU`A=0a4bLleTG7K_qQcC>Dy8T|v?|Z3Ai2lSzPr3lwEj z3@ErSAc%m7xL)P5C@v^ocX8v2;&Sz?UKd1h_xH|wCTUUc{odz3&-afXJe_%G&dj{; zY@ahT=Okg%QI;pSAvP0bd72tx7ov=_lFddL+mK-!GP4cquqEr!ZA5o2x&d^9;5KU( zSd%nssp!fRt!7-cHX~u0X_Ab`bzn2Kp)B8(HIPLHvdF-c2C~RN78%GQ16gDsiwtCu zfh;mK$s$9OW5duSiwsS&$Uqhunrst8lPoec*(Qc2S!8IEMFz6Sfb$2LOR~s778!7V zm$GD$0rz+5N){RT1i?TS8OS07S!5uK3}lgkEHaQqh9+5LXp%(+vdGXRiwtCup-C1Q znq-lIEHX67B14lbGLS`vCRt=?l0}9lS!8IEMTRC>WN4B_h9+5LAd3uSk%25SkVOWv z$bdD8v|qBwKo%LuA_Jds7|0?6pL7_=A_Jdy7|0?6S!5uK3}lgkEHaQq2C~RN78%GQ z16gEfl0^ox$iQbM2C~RN78%GQ1D~51nq-loNfsH%B7;a48OS07pQ;$hA_G}uAd3uS zk%25S@HvZtEHa2>k%25Sh-8t0EHa2>kwGMj3?f-%5XmBgNER7HvdDmQC$I$0oun&S zWWf3j+6`G`Ad3uSk%25SkVOWv$Uqhu$RYz-WFU(SWRZa^GN_zK@FuA&6IlfBMWQTO zWWWwc#!D6%un&^5WRbxniwxKeNm;VUfIX3vC5sH$8A(~P$bkKklqHJ{*d<9>vdDnF zl9VNj4A?PAS+dArl0^oSEHap6k-;R33?^A*Fv%i=NfsH%A_G}u;Ik(KS!Cc7C<9q! z;BzPgS!5uK3}lgkEHaQq2C~Rtl0^ox$Y7F12C~Rtl0^ox$Y3}tkwpeRu`-ZF2C~Rt zl0^oSEHap6k-;R33?^A*Fv+4YvM7u!3IkzwL5w_I4Q3P4E268QiJzJ`DA&qox;KqcG3ovV-AB;f zgYI9kc6-r<-)?|3`_Vms)*i$(PoS%ZmZcWQ^S9#eil~mb<(d z&`ip5mlp$?N%>`TUq$x_x^JKh-yaB9;Tx;Kh3^jpSFWsLKr<=JU0w`mCgt~0{s3jU z%ZmZcWc-iPa-f-XlhI8_SMKs+Kr={#G>ZYvq%1!>69bw_S?=;;Kr<=Ab(qT?e}P=sMAr?}WsFZ!kiDZ_*u&ZYgTP@d6~)X1wqKahcb za24n$Wjo6KQ0|ZN87QBL?pYW!5amHA4@P+i%0p2ehH?(dxhM}uSx4D{avsY0C>Nky zh_Vaav(X)i?r3yN&@Dr^Le?GVC#{vc!Whs`%5qm21Nuo>?h0c_zZlR@#>mgb#DIQM zmYvZhaQ0+DH&wd8H0j#3!J7QngN)J$N}5&-z9|ze1wy7wwIr=X$xQ15 zr)Fk6ZQLdmfA)D|l_S?jDluVkCnOFORQG%Z*AMak(}E*Yxi3~dOR zp}|*O@f5HtOqMB`Xr0KnN~Rioa$d+#CvfBmPh@x2o9}v{!qBVv?^R8t{hQqShCz^M&m>_QWN7 zNz@;xvpaNssxK@cm)();(B);Bu`QWj*uC~h*jwjo@`mTxL-lcm-e8@*$=hPD@!7+^ z2ET~-!eFUCXs`8!BVO?5M#Fwl=dYC}iQI$@?F?;H!? z{NG)Rv^4wbe8S%l1k-aHBTa!yKh#iw{wUTn(&)3ho4vK*sVl?m@oMJf>g~(MRJoyW z!|;Gvh8SL1QRf)8v}UbE3uCHAh_!3m z;V)0qH3$5`E7T}Cv|$iC22zKhv;dT2*GfSSLvHEH^86qLVW?I?oDU?sRt@n%80wQC z+@M7vpBK`)A*L2n)PWm@bUE<%$6R)pR8c53fHq5ObZsi;5K5OFY|KSFMN&z+9+-Y+C{4_@UPERuW+MAKT&2TU7Q+1lsg$Z8-d2fd6wr!|AOkds6mBF7{~? zr2KF5MWC*-2W9)nmTrKW$XZF8WtmOTBb8Vi*~sn40%9rwzonW-n*gKFgX340sZo>QztuxG|H(hL zgHXZix*$T)HysU+jc1X4vNlJm(VQcWh4DP$^{My8V)WG1X1sU>y9N9sufX(WC!m&_vp(nNwJM4E{~!bFe=iIVwb0a-{|$Re_sTud$@ zmy*lK60(%El4ay_as^pVR*;os6dko*|ZDoO1shSv)wH&!7Y7ne;3=kPf1Q=@2@U z4x>3Vmky^obqQ&%VI)aX*=g?8~TsoS%X$dW*Wz<8<=@>eeR?uxtI*m@JGw4iu0flGcbT+++&Y@mfLu+Xr_0f9TKpUx_ z&ZYBcfHu(}4bf(5&@dG=LZfs(T|gJo7P^QorWeyo=%w^Bx`ZyJt#lc^oL)hf(-m|j zT}4;ZE9q5q4ZWJi=vumtUPG^?>*)r19lf63KyRcs(VOWl^j3Nsy`65Po9G>MGu=Y( zq+97-bQ|4HchI}(PI?dBMen7%>3#Hm`T%_pekcB6_`T>y=%aKG{3h#Ox{vOs2k2w; zae5Gbhx1AJMa!q@A^Hq`7Jk9;Irv4v=jjXdMfwtbnZ80_rLWN=^mX`Uy*J_4=H7;1 zZ2LQXhaRKv!ta_Lhu^#UfPM(S0Q3*~G5v)85B-#WMn9+jq+if4=~wh?dV+pKPttGc zckm77-_sxHkMt+{GyR4B3g0=ZF#=yJ$>1CIEX)euik8e$SSozSRT_iuGJ9?+y0advC+h{DkM9GY(YCXGtUo)04Pa-ov)Dj3hz({#*ibf%<*-~f zoaxNL@>o7AU`|%ZikOQPv$NR_Rq+&1M&|Iq=lJhSjn<=7T5V4e-3$&*rju zEWnyr5T2tn!|7v~2^L{dHlHnE3t07$>^62g+sHPtJJ@Enh26=v zvb)$eww>)@ce9=B9=40!%XYK-*!}DQ_8@zRJW*x%Um>;?8Bdx^cwUSY4Y*VqyEI(vh?$=+gbv!m?q>>YND zz02NX$JzVr1NI^Ni2Z|o%syfN!#-u7vCr8**%$0f_7(e@onYUvlk8je9XrLoXFsqX z*-z|e_6z%!{l+y;IOU9UZsAs*#FKdnPvthA#?yHQ@4z#8N8X8N@yOx-U%{926?`RM#aHty`Bi)kznaJRTE327!>{G* z`38O+zn15op0ou_#J#R-@@S z>MSDQ6^(q6FC1c_ppQisge;N9un*cV6bfqT|Km`Z07U^*xUttO(AT7)Ig}gU+WFPXiAC({krZh zOKsb-rG)0gu#k1P*7=|hU`RlxLpf1lgKia3?D23qc5ggn@zzEoKH3zOc&^k6 zOe2R|Y6Yf~Vuy;hv@)Dt5l=5e%oAy}PC)h6DpN(3siLYao3+ZcuPUB1xhWcm_?rVQ z)+!vO)+uJzDQ4CwZCO*M#Pe8Z;6=;i#!xtz+TaT}!L+Uk2&?Rh`97=H%co7yaHjCGnTpMo|=zW>lXJ+=bWln*vG>4njZ>I5^Y1I6Y?VjR~r(r&5hM?ID zAv1Z%Ode`0(i$@D3B_|+>-_Wmbv|pzY=o$pF=}Rvwq;C-CUUgkMc@uJLP|?KI?3JS ztqq5QNnX>px?#r2HbF1R9cqB#H806)`qok`#9C`ADs59_t8J5cXPv`89%Y?RS?4he z_MvAR(`J#ap-r}qF-vYhkB^bIHh_~h2FYz|No!~qu#IiYZEI|k`B-2KZP zHn&YqJFlJ5Y4c7CNK^#_Fz)@e)=IMz1L&nywoeym7qC{E%^5(CSIUM8fMcyR2VKDQ zCYYrK&C({cDF98;zug+J|VBhlYICNv0)mV*%QxO=_n+E!-|(on%@PHoa;ymq5=}-PW8o zxaGR>0^Nt!eB%Cl=d}GkG2mbO;HmfYWlWmZ8fkhXeZBTC%3f8DKp|& zu+B7FWf6L*GZRBHbx}gJ&NOSb2t5m|R2qb}J`e&cQ}Hfh=0$R%nB+F^AxT~ZO%vgG z&1RAe<+SQ{?Ux2OTUb!3$=_zH#Z+!Kmj#xEM1sChk}6(cQ}pVvTgOM|SWrOp?Kc#~9Fup)*k z%8PIW9r1Emm}MST4_4_=J=4&VQW}iXh5n?Fs$;XCg&RXwShhEL9TxOh1gfe`V9ij? zTKEHtEFswkX|m+FWgUKJX__k5>_Bx91F4u9#T0M7-w((CdHHe4=}1U<390RBLAuJ} zbjp@ZgbHOSk-jJ)xe`)wTq@KPQbJc@T$iK38NcdCl;TK~;z*Q|mnbDKQA%FC6g{sX zUP@k~yu89hT%zQ>M9F!HlJgTK=O;?ePn4XWXp8)Wj{Jm<{DhADgpT}#j{Jm$WfTcQIxQ%C}B%c!j__h zEk%ivixMRlB}y(zlw6c3*_9~Sm8h>Pp~IEX;Y#RmC3LtFI$Q}Iu7nO(LPv2zM{z<& zaY9FNLPv2zM{z<&aY9FNLPt?sDRCVzQ`8u8=<%x#J+8x{$8|XLxDJON*Wu9PIvjdj zheMCo!=Wd1I1)PAY<9-u^kSEFnz<}qV0zQ==3-rdUdpsM4pJ7xCF=|`VT#GSyyp^0}e2RB(o_YVavGj|#4o@mIpX&Q z>iqTfmNL9wG>1cV(b`Cgh{8QYT5Q1`cM?2km0R^>f3O~Q@{tx0B643Au)$3v99oD+ zCCTz`F3(I-ad8n}htJK#g-5$Z ziLIU7v7H>2w?4z(CHZEFdcIjA`1!ms6q+Zyti~4zEx=R-Dpi4Q>ML-X_7^x+xKM=)&3Y6Rn)N6s zL@V@yLTpFyu^qw3`hkz_2tKwW_}Gr%V>^P6?FhcvP6dT=eb_D#kL{ut6e;~hN`H~k zU!?RGDg8xCf05E(r1Tdl{Y6TDk(qE+XyOe&H((h9GT}r=8>31pp zE~Ve4^tzN@m(uG}dRzp^tn|%-Kw5$rQfaeyOn;o((hLK-Acb(>31vrZl&L?^t+XQx6=p-kCOrfeuvHk2tF%9IUdsvXKyKX{aWk7@&t zY6Fkb?@{_aO20?7fk)~0DE%I#-=p+IARcRI}WcRI}aI~`{IoetFR@R;)y ze7p`mUI#yZ9qofK+6O+`2R_;dKH3L9+6O+`2R_;dKH3L9wh#DdANXjW!(+}<@RfdZ zoTk|b2&?*+7Rk8=VOM;vfn2QO-0k9&9p+qxG|G-r)efb~4s)J5Jmx$FU)f>KQwS?N z%y|l7WrsOWA*}kroTm_0{b0^h2&;ZD=P87hesi8WJmx$FU-g4IPa&-O!JMZMR{dbk zQwXbmFy|?RRX>>X6vC?h<~)V4s=ql;A*||e&QpiSoTuQc`kM0+!m7UJyo9i-uQ@OC zbah|I*UPioj<0YN0*l3(c5%4vka3;b(#dtq?~>tpmW<25g=wNBGngnO9k0gon->#V zGvjMpd0lQ2I>sYv;OQg8O)33-Ol4^@EaY>W;gM;QT+`-;gjGg>2M@l$OUBhb2uX64 zi#{xH<#kxw%ImnSl>)A4WdgaF1)tW}%iB?&BTrAB96xA{D8bSohir#-C-^d)Y98N9 zFkoO+m7RD#kdrC zVulAoTuN!uiEkg(hF5pSH?q1DM}}Tt&Sdc8Gh2<2Qnvxb z5C4#F5auhv94Tmx4bo?59pMe(u38U_PX!CC@P=_3SkXc2q-AT}w4UmU1>Q)O_EWGV z3+(O=HuMho8@$?XbRR}{ZvY04b`afX(0w5gststbq5F17UVRVUPtg5J4m9n1bbpmD z;X-z4D!QG}?IDEjApOxDf^HtTdE{(#N26N~Za%3*cM`hOBeJyF=+>hf#P*TzHOn`x z+uS6S+q=maBVBln3)D9+R$o8&LM$f9kjOb6cOwID(~^E`@iXE5g+TPKD zutggO|26Gh_)p+X^5YQq0sLp$NARCRC>O@kFzsqBrmfZ1X`gDJYhP$zX(zOk@Md8H zyd$`Y+yQT4y$Nq5je*nz-uu~(wd30TA{k1{x4HXPtC9Q(*tB`&reBy~}71RlC z6)ga_Qfh}Q@}HE<@t|eThHz($)v~ARt=W^TDMOZzU4AN^B+-qn*`*M5E+xca(^IUL zp&5+!uxPs1nmW`9ub;LSQNlM?>*wpk+Qsy`qtB9F+DQCg1#ck>c>h(tgDu}b9wq z?_Ifk&fqTNE*O5^x_K+sedC-w-TCRug|lnMPddNAIJmgJ_o`>!8S>=Z)bEPkx*@Xe zyK8pserW!6UvD2*>lu?f&vwm(^M+pa#q@DkzLxZ1k73`p?wJ18^CjQpJQh8+=I%pR z_r57mnY^LTv7=u$91kC?IC$Hfk;mWP-(_>{LVxGQ_vBCpgJ|>8C-tR|>jlFducv(JQhWheh`Vf84 z#Er-iO|_{JQe!*X!0jFtx|%t)E@9-&MRjS{OO|hN=&X_T0GY@P?A!yB|HY zam}>%emqjgOPmwP%lUV7eP;ZQfrm~UUtURF zf1ve>C*~Y~_ntv-9=h|qy0;JYykOtX;^ZT){+sfz9KQOd&-NzuJGac8lJt{o(o;v9#-=;A{I1FLrB}9_2{YY}Y&}ahadKALG&slgg@g7| zZ?n(QS??sHld^1O(Qu77IA6Xu74MJKEbHV(?}CWW(Od5+li9L5n-TU>IH~s6!%?j~ zyLI%{dz<~&MO~H?Sj6YAnzs2cQ{l)iK5b<%KR#{$Pgv1P`nPWtIbB;x2TgA!sZ@@r z?T7E*^0(*h_oiO5YUhgRR}W73`rXGn9BA4S_ppO5Z!>7(h#&OP+tyDRoxv}mp)m)*EDYugz63l5P!E$8`#1^F8~-Pq~T zV~xXi{NsaztFIdJ#FhP4)bCq1eOf4bVC0UoR?Iq_nLYCM%Rim`cxv#;U!NNH&Z9{k zukU~H(NP0m?z8ao+a1q-{g3|Lk3RXpn9`eiT(q&z+7D-c`^CjyUvhU1iG4fXcI>78 zQ@3q+e%H$RyS~_y{>_Ku-`e<72 zXHVC_Q|FG;TlvrM=Tr08H|eb7_vdyyKBL3nD|Yt(_`=^=tY6e_8vnbyXp!!O27wux zTMDnH3VXhNVzdSxb=W6{;h{~q<@6bAcSq%GWAK0l@2JJPGY=l{#iynW!gF!+j=J>W z|Ih*j0b5p=wp(gADkAm?KG;r%=Q&2`#iogQli`g$AwNqO6+XK+VwZOop*{)M{+2X6 z-0ZavsvWEsgLSzwGs_y7C_P@$(oh|&7T_)>7Yp#Tq&O!}E*1W_>A%0B_k(kGz#9`& zyIx%X?Cj;~N50;9m$B^XD_4CFFED3Y_vBpOZ^MT#-!ifCr&s##d;7%w&JlfLPo(_x zb5`!m1FJ4RXT+I(zWZkS;#*FVhn`M-WXTKr2S&UN1IN$(=<}uC=`EYz>zdgqd*JTl z;|neuI>ui1=&||%^{bz++SB(b*E5sX9uI%ly*@hk(Tc_wT`lQ5^le9n%^7>!8#_9a z?aSV9t<#IMu489kJbLoO_q;c}=d!o{o?ec+9uzw~?ft_wGJux;O(IWeOkcl=#1 zJUjc$*RI<8P4MEud&#Vy9V=!Yx$26B=_|W$JmCE5)1jODeZ2O&Wgl((=bVMJ7tdMt z%QV|8cY5vQIj@)Y`_i2Lt>h@Q)Ejsk`2AFFmQ&2m{d$A$v)bk?A4`^h?;%NDnLbq? z6u-Mu(xunG?7!M(p$|!5>AY zy1_TR!Cw!n*S>m^S`72fv5#Kuv3%#6tLHuO;*z*S=)D|0^llIVW4|K~`TWuZ;GCw(8St@!&ey**Z`)bT&ult(ec$AqC!IHM z+0^I6?`R_VcO`r5o%L_J@9_F}XK!10NPl|m$V*F34S4v&Wuhy*%b$76ruTnbI{dT8 z4wro#esAK#Q!?$#g4bR1;Z5hyeXz*!_d9bwyGlFMyXxcdd3&z-e!~7A8>aZan!A6| z;W}53%*=(J`HpXvFJc|$9DHEbt>0Z)Kfkr-jN{8b+E;O>YwAbG+zT?MchFlcS+I`z zN%61#gRdG|4rh01nphoL*}ccI-&w5xe~Ta3sQ|Q!@`~HI3hx@|t^`+KI-RR>&_O3B zXQht^e#2*XfsK)fh_A(xvaHiWHSoCy2aE`rFtu~`czEeeeiqmc2VD&kez>0+rH_=? zZCU0AsJ#JuMVUR$${hQ6`Bs?-)ko~r;4FZTKiH>w1Ah33HLT?9^Ya|ta23yOojXjH zWy43I&5u=!xMub*H2>S}(fYED8~hhfNq^~Rmo<6L)s^{o&$e%>d}GK8*Bdw7Ir^*a z6}J9;s;dr`ZasYE_NiY6$6B{pvWxrFju_Bs?V~rmcsSX4N%(^?(|&1rZuPj2M>pp< zYcJci5GI^;lKSzh#)yATY&gJ>>eUGTkhpmacz2y91 z>XufQ#xLRw#!~ENDW{_oI1oq5zeT6S;h!vom>!L1hs~Wt^MAIvJ2#$7r+-=_uitw* z7Eh~@FRb^K?Q#Z((Xr&uQPa_yV%{Q3z%bb6@k|&}~(C z!?h_d_3l2ktm_>szxip+t-DU8JCBV_+gY}Lj%Uctzup|G9C2SkLv!Zx-)0tHIP-%* z>)pnm$JZ>H_t1i}eQEccoOR}~51wDGk2;Ut(sFp~gk83Se;bfwdwhNC zcbQ-BS^MzKH@$h`$gHnFrPgi($B$eU%3uBJ@?-xqJwJNRXV?1QFAGi30xur9;_azh zZ`yk9bCvxX*PfWO=lCbqS;hUb^8V>)WetGET1tq%^tu0Uu}3ri0Q9zVs*TNhX1fuQ z=8)$M-4mxqDa?`9?lK3?wGAJeBLfa7+QQlT8EqN41MYugKlt=$*V@?A_hnBTX#b1v zWcTU~-P(^d*#GgROFSd?zP9Jfw|gF_8F8%B=i{uGdkpup^w->s4d1M~Z_-KkXH9v- z#vT~FZtwlWXVncT$lY_@gAb1r*T47O?e0^j8Xx|4iFKiSfA!kOE?qe3f?hi^`jz~B zf66WSua-|-JHm2f=Fl1b&#!p1_T`)>tk)I%v-9R#PJBIi^pP=LH`=tmSJi)cY*f!p z5|eI6pL_ACTOPk`@wIa%^n7yYv<>T@>vH_2hWwX@4$gY! z^Zk2g+{d;IzVY+kD{maIVnK(S4|o3Qwbv>tBN@+}lN+)>%bx$_qYf|iD}G>V_ai^; j+_!VPYv1l8X`A1wy=V7^2OFn9@%|fwe_OZZkf!}Vb520^ literal 0 HcmV?d00001 diff --git a/vendor/endroid/qr-code/composer.json b/vendor/endroid/qr-code/composer.json new file mode 100644 index 0000000..03a54d6 --- /dev/null +++ b/vendor/endroid/qr-code/composer.json @@ -0,0 +1,54 @@ +{ + "name": "endroid/qr-code", + "description": "Endroid QR Code", + "keywords": ["endroid", "qrcode", "qr", "code", "php"], + "homepage": "https://github.com/endroid/qr-code", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Jeroen van den Enden", + "email": "info@endroid.nl" + } + ], + "require": { + "php": "^8.2", + "bacon/bacon-qr-code": "^3.0" + }, + "require-dev": { + "ext-gd": "*", + "endroid/quality": "dev-main", + "khanamiryan/qrcode-detector-decoder": "^2.0.2", + "setasign/fpdf": "^1.8.2" + }, + "suggest": { + "ext-gd": "Enables you to write PNG images", + "khanamiryan/qrcode-detector-decoder": "Enables you to use the image validator", + "roave/security-advisories": "Makes sure package versions with known security issues are not installed", + "setasign/fpdf": "Enables you to use the PDF writer" + }, + "autoload": { + "psr-4": { + "Endroid\\QrCode\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Endroid\\QrCode\\Tests\\": "tests/" + } + }, + "config": { + "sort-packages": true, + "preferred-install": { + "endroid/*": "source" + }, + "allow-plugins": { + "endroid/installer": true + } + }, + "extra": { + "branch-alias": { + "dev-main": "6.x-dev" + } + } +} diff --git a/vendor/endroid/qr-code/src/Bacon/ErrorCorrectionLevelConverter.php b/vendor/endroid/qr-code/src/Bacon/ErrorCorrectionLevelConverter.php new file mode 100644 index 0000000..ae2be59 --- /dev/null +++ b/vendor/endroid/qr-code/src/Bacon/ErrorCorrectionLevelConverter.php @@ -0,0 +1,21 @@ + BaconErrorCorrectionLevel::valueOf('L'), + ErrorCorrectionLevel::Medium => BaconErrorCorrectionLevel::valueOf('M'), + ErrorCorrectionLevel::Quartile => BaconErrorCorrectionLevel::valueOf('Q'), + ErrorCorrectionLevel::High => BaconErrorCorrectionLevel::valueOf('H'), + }; + } +} diff --git a/vendor/endroid/qr-code/src/Bacon/MatrixFactory.php b/vendor/endroid/qr-code/src/Bacon/MatrixFactory.php new file mode 100644 index 0000000..1d6a9a2 --- /dev/null +++ b/vendor/endroid/qr-code/src/Bacon/MatrixFactory.php @@ -0,0 +1,32 @@ +getErrorCorrectionLevel()); + $baconMatrix = Encoder::encode($qrCode->getData(), $baconErrorCorrectionLevel, strval($qrCode->getEncoding()))->getMatrix(); + + $blockValues = []; + $columnCount = $baconMatrix->getWidth(); + $rowCount = $baconMatrix->getHeight(); + for ($rowIndex = 0; $rowIndex < $rowCount; ++$rowIndex) { + $blockValues[$rowIndex] = []; + for ($columnIndex = 0; $columnIndex < $columnCount; ++$columnIndex) { + $blockValues[$rowIndex][$columnIndex] = $baconMatrix->get($columnIndex, $rowIndex); + } + } + + return new Matrix($blockValues, $qrCode->getSize(), $qrCode->getMargin(), $qrCode->getRoundBlockSizeMode()); + } +} diff --git a/vendor/endroid/qr-code/src/Builder/Builder.php b/vendor/endroid/qr-code/src/Builder/Builder.php new file mode 100644 index 0000000..89c6441 --- /dev/null +++ b/vendor/endroid/qr-code/src/Builder/Builder.php @@ -0,0 +1,128 @@ + */ + private array $writerOptions = [], + private bool $validateResult = false, + // QrCode options + private string $data = '', + private EncodingInterface $encoding = new Encoding('UTF-8'), + private ErrorCorrectionLevel $errorCorrectionLevel = ErrorCorrectionLevel::Low, + private int $size = 300, + private int $margin = 10, + private RoundBlockSizeMode $roundBlockSizeMode = RoundBlockSizeMode::Margin, + private ColorInterface $foregroundColor = new Color(0, 0, 0), + private ColorInterface $backgroundColor = new Color(255, 255, 255), + // Label options + private string $labelText = '', + private FontInterface $labelFont = new Font(__DIR__.'/../../assets/open_sans.ttf', 16), + private LabelAlignment $labelAlignment = LabelAlignment::Center, + private MarginInterface $labelMargin = new Margin(0, 10, 10, 10), + private ColorInterface $labelTextColor = new Color(0, 0, 0), + // Logo options + private string $logoPath = '', + private ?int $logoResizeToWidth = null, + private ?int $logoResizeToHeight = null, + private bool $logoPunchoutBackground = false, + ) { + } + + /** @param array|null $writerOptions */ + public function build( + ?WriterInterface $writer = null, + ?array $writerOptions = null, + ?bool $validateResult = null, + // QrCode options + ?string $data = null, + ?EncodingInterface $encoding = null, + ?ErrorCorrectionLevel $errorCorrectionLevel = null, + ?int $size = null, + ?int $margin = null, + ?RoundBlockSizeMode $roundBlockSizeMode = null, + ?ColorInterface $foregroundColor = null, + ?ColorInterface $backgroundColor = null, + // Label options + ?string $labelText = null, + ?FontInterface $labelFont = null, + ?LabelAlignment $labelAlignment = null, + ?MarginInterface $labelMargin = null, + ?ColorInterface $labelTextColor = null, + // Logo options + ?string $logoPath = null, + ?int $logoResizeToWidth = null, + ?int $logoResizeToHeight = null, + ?bool $logoPunchoutBackground = null, + ): ResultInterface { + if ($this->validateResult && !$this->writer instanceof ValidatingWriterInterface) { + throw ValidationException::createForUnsupportedWriter(get_class($this->writer)); + } + + $writer = $writer ?? $this->writer; + $writerOptions = $writerOptions ?? $this->writerOptions; + $validateResult = $validateResult ?? $this->validateResult; + + $createLabel = $this->labelText || $labelText; + $createLogo = $this->logoPath || $logoPath; + + $qrCode = new QrCode( + data: $data ?? $this->data, + encoding: $encoding ?? $this->encoding, + errorCorrectionLevel: $errorCorrectionLevel ?? $this->errorCorrectionLevel, + size: $size ?? $this->size, + margin: $margin ?? $this->margin, + roundBlockSizeMode: $roundBlockSizeMode ?? $this->roundBlockSizeMode, + foregroundColor: $foregroundColor ?? $this->foregroundColor, + backgroundColor: $backgroundColor ?? $this->backgroundColor + ); + + $logo = $createLogo ? new Logo( + path: $logoPath ?? $this->logoPath, + resizeToWidth: $logoResizeToWidth ?? $this->logoResizeToWidth, + resizeToHeight: $logoResizeToHeight ?? $this->logoResizeToHeight, + punchoutBackground: $logoPunchoutBackground ?? $this->logoPunchoutBackground + ) : null; + + $label = $createLabel ? new Label( + text: $labelText ?? $this->labelText, + font: $labelFont ?? $this->labelFont, + alignment: $labelAlignment ?? $this->labelAlignment, + margin: $labelMargin ?? $this->labelMargin, + textColor: $labelTextColor ?? $this->labelTextColor + ) : null; + + $result = $writer->write($qrCode, $logo, $label, $writerOptions); + + if ($validateResult && $writer instanceof ValidatingWriterInterface) { + $writer->validateResult($result, $qrCode->getData()); + } + + return $result; + } +} diff --git a/vendor/endroid/qr-code/src/Builder/BuilderInterface.php b/vendor/endroid/qr-code/src/Builder/BuilderInterface.php new file mode 100644 index 0000000..9a14dc0 --- /dev/null +++ b/vendor/endroid/qr-code/src/Builder/BuilderInterface.php @@ -0,0 +1,45 @@ +|null $writerOptions */ + public function build( + ?WriterInterface $writer = null, + ?array $writerOptions = null, + ?bool $validateResult = null, + // QrCode options + ?string $data = null, + ?EncodingInterface $encoding = null, + ?ErrorCorrectionLevel $errorCorrectionLevel = null, + ?int $size = null, + ?int $margin = null, + ?RoundBlockSizeMode $roundBlockSizeMode = null, + ?ColorInterface $foregroundColor = null, + ?ColorInterface $backgroundColor = null, + // Label options + ?string $labelText = null, + ?FontInterface $labelFont = null, + ?LabelAlignment $labelAlignment = null, + ?MarginInterface $labelMargin = null, + ?ColorInterface $labelTextColor = null, + // Logo options + ?string $logoPath = null, + ?int $logoResizeToWidth = null, + ?int $logoResizeToHeight = null, + ?bool $logoPunchoutBackground = null, + ): ResultInterface; +} diff --git a/vendor/endroid/qr-code/src/Builder/BuilderRegistry.php b/vendor/endroid/qr-code/src/Builder/BuilderRegistry.php new file mode 100644 index 0000000..13b9c96 --- /dev/null +++ b/vendor/endroid/qr-code/src/Builder/BuilderRegistry.php @@ -0,0 +1,25 @@ + */ + private array $builders = []; + + public function set(string $name, BuilderInterface $builder): void + { + $this->builders[$name] = $builder; + } + + public function get(string $name): BuilderInterface + { + if (!isset($this->builders[$name])) { + throw new \Exception(sprintf('Builder with name "%s" not available from registry', $name)); + } + + return $this->builders[$name]; + } +} diff --git a/vendor/endroid/qr-code/src/Builder/BuilderRegistryInterface.php b/vendor/endroid/qr-code/src/Builder/BuilderRegistryInterface.php new file mode 100644 index 0000000..0d9fb37 --- /dev/null +++ b/vendor/endroid/qr-code/src/Builder/BuilderRegistryInterface.php @@ -0,0 +1,12 @@ +red; + } + + public function getGreen(): int + { + return $this->green; + } + + public function getBlue(): int + { + return $this->blue; + } + + public function getAlpha(): int + { + return $this->alpha; + } + + public function getOpacity(): float + { + return 1 - $this->alpha / 127; + } + + public function getHex(): string + { + return sprintf('#%02x%02x%02x', $this->red, $this->green, $this->blue); + } + + public function toArray(): array + { + return [ + 'red' => $this->red, + 'green' => $this->green, + 'blue' => $this->blue, + 'alpha' => $this->alpha, + ]; + } +} diff --git a/vendor/endroid/qr-code/src/Color/ColorInterface.php b/vendor/endroid/qr-code/src/Color/ColorInterface.php new file mode 100644 index 0000000..398be26 --- /dev/null +++ b/vendor/endroid/qr-code/src/Color/ColorInterface.php @@ -0,0 +1,23 @@ + */ + public function toArray(): array; +} diff --git a/vendor/endroid/qr-code/src/Encoding/Encoding.php b/vendor/endroid/qr-code/src/Encoding/Encoding.php new file mode 100644 index 0000000..d6da27b --- /dev/null +++ b/vendor/endroid/qr-code/src/Encoding/Encoding.php @@ -0,0 +1,27 @@ +value; + } +} diff --git a/vendor/endroid/qr-code/src/Encoding/EncodingInterface.php b/vendor/endroid/qr-code/src/Encoding/EncodingInterface.php new file mode 100644 index 0000000..17748a4 --- /dev/null +++ b/vendor/endroid/qr-code/src/Encoding/EncodingInterface.php @@ -0,0 +1,10 @@ +getText(), "\n")) { + throw new \Exception('Label does not support line breaks'); + } + + if (!function_exists('imagettfbbox')) { + throw new \Exception('Function "imagettfbbox" does not exist: check your FreeType installation'); + } + + $labelBox = imagettfbbox($label->getFont()->getSize(), 0, $label->getFont()->getPath(), $label->getText()); + + if (!is_array($labelBox)) { + throw new \Exception('Unable to generate label image box: check your FreeType installation'); + } + + return new self( + intval($labelBox[2] - $labelBox[0]), + intval($labelBox[0] - $labelBox[7]) + ); + } + + public function getWidth(): int + { + return $this->width; + } + + public function getHeight(): int + { + return $this->height; + } +} diff --git a/vendor/endroid/qr-code/src/ImageData/LogoImageData.php b/vendor/endroid/qr-code/src/ImageData/LogoImageData.php new file mode 100644 index 0000000..2e3358e --- /dev/null +++ b/vendor/endroid/qr-code/src/ImageData/LogoImageData.php @@ -0,0 +1,159 @@ +getPath()); + + if (!is_string($data)) { + $errorDetails = error_get_last()['message'] ?? 'invalid data'; + throw new \Exception(sprintf('Could not read logo image data from path "%s": %s', $logo->getPath(), $errorDetails)); + } + + if (false !== filter_var($logo->getPath(), FILTER_VALIDATE_URL)) { + $mimeType = self::detectMimeTypeFromUrl($logo->getPath()); + } else { + $mimeType = self::detectMimeTypeFromPath($logo->getPath()); + } + + $width = $logo->getResizeToWidth(); + $height = $logo->getResizeToHeight(); + + if ('image/svg+xml' === $mimeType) { + if (null === $width || null === $height) { + throw new \Exception('SVG Logos require an explicitly set resize width and height'); + } + + return new self($data, null, $mimeType, $width, $height, $logo->getPunchoutBackground()); + } + + if (!function_exists('imagecreatefromstring')) { + throw new \Exception('Function "imagecreatefromstring" does not exist: check your GD installation'); + } + + error_clear_last(); + $image = @imagecreatefromstring($data); + + if (!$image) { + $errorDetails = error_get_last()['message'] ?? 'invalid data'; + throw new \Exception(sprintf('Unable to parse image data at path "%s": %s', $logo->getPath(), $errorDetails)); + } + + // No target width and height specified: use from original image + if (null !== $width && null !== $height) { + return new self($data, $image, $mimeType, $width, $height, $logo->getPunchoutBackground()); + } + + // Only target width specified: calculate height + if (null !== $width && null === $height) { + return new self($data, $image, $mimeType, $width, intval(imagesy($image) * $width / imagesx($image)), $logo->getPunchoutBackground()); + } + + // Only target height specified: calculate width + if (null === $width && null !== $height) { + return new self($data, $image, $mimeType, intval(imagesx($image) * $height / imagesy($image)), $height, $logo->getPunchoutBackground()); + } + + return new self($data, $image, $mimeType, imagesx($image), imagesy($image), $logo->getPunchoutBackground()); + } + + public function getData(): string + { + return $this->data; + } + + public function getImage(): \GdImage + { + if (!$this->image instanceof \GdImage) { + throw new \Exception('SVG Images have no image resource'); + } + + return $this->image; + } + + public function getMimeType(): string + { + return $this->mimeType; + } + + public function getWidth(): int + { + return $this->width; + } + + public function getHeight(): int + { + return $this->height; + } + + public function getPunchoutBackground(): bool + { + return $this->punchoutBackground; + } + + public function createDataUri(): string + { + return 'data:'.$this->mimeType.';base64,'.base64_encode($this->data); + } + + private static function detectMimeTypeFromUrl(string $url): string + { + $headers = get_headers($url, true); + + if (!is_array($headers)) { + throw new \Exception(sprintf('Could not retrieve headers to determine content type for logo URL "%s"', $url)); + } + + $headers = array_combine(array_map('strtolower', array_keys($headers)), $headers); + + if (!isset($headers['content-type'])) { + throw new \Exception(sprintf('Content type could not be determined for logo URL "%s"', $url)); + } + + return is_array($headers['content-type']) ? $headers['content-type'][1] : $headers['content-type']; + } + + private static function detectMimeTypeFromPath(string $path): string + { + if (!function_exists('mime_content_type')) { + throw new \Exception('You need the ext-fileinfo extension to determine logo mime type'); + } + + error_clear_last(); + $mimeType = @mime_content_type($path); + + if (!is_string($mimeType)) { + $errorDetails = error_get_last()['message'] ?? 'invalid data'; + throw new \Exception(sprintf('Could not determine mime type: %s', $errorDetails)); + } + + if (!preg_match('#^image/#', $mimeType)) { + throw new \Exception('Logo path is not an image'); + } + + // Passing mime type image/svg results in invisible images + if ('image/svg' === $mimeType) { + return 'image/svg+xml'; + } + + return $mimeType; + } +} diff --git a/vendor/endroid/qr-code/src/Label/Font/Font.php b/vendor/endroid/qr-code/src/Label/Font/Font.php new file mode 100644 index 0000000..e796c55 --- /dev/null +++ b/vendor/endroid/qr-code/src/Label/Font/Font.php @@ -0,0 +1,32 @@ +assertValidPath($path); + } + + private function assertValidPath(string $path): void + { + if (!file_exists($path)) { + throw new \Exception(sprintf('Invalid font path "%s"', $path)); + } + } + + public function getPath(): string + { + return $this->path; + } + + public function getSize(): int + { + return $this->size; + } +} diff --git a/vendor/endroid/qr-code/src/Label/Font/FontInterface.php b/vendor/endroid/qr-code/src/Label/Font/FontInterface.php new file mode 100644 index 0000000..1c0de9a --- /dev/null +++ b/vendor/endroid/qr-code/src/Label/Font/FontInterface.php @@ -0,0 +1,12 @@ +size; + } +} diff --git a/vendor/endroid/qr-code/src/Label/Label.php b/vendor/endroid/qr-code/src/Label/Label.php new file mode 100644 index 0000000..d7a7aba --- /dev/null +++ b/vendor/endroid/qr-code/src/Label/Label.php @@ -0,0 +1,49 @@ +text; + } + + public function getFont(): FontInterface + { + return $this->font; + } + + public function getAlignment(): LabelAlignment + { + return $this->alignment; + } + + public function getMargin(): MarginInterface + { + return $this->margin; + } + + public function getTextColor(): ColorInterface + { + return $this->textColor; + } +} diff --git a/vendor/endroid/qr-code/src/Label/LabelAlignment.php b/vendor/endroid/qr-code/src/Label/LabelAlignment.php new file mode 100644 index 0000000..b609fe4 --- /dev/null +++ b/vendor/endroid/qr-code/src/Label/LabelAlignment.php @@ -0,0 +1,12 @@ +top; + } + + public function getRight(): int + { + return $this->right; + } + + public function getBottom(): int + { + return $this->bottom; + } + + public function getLeft(): int + { + return $this->left; + } + + /** @return array */ + public function toArray(): array + { + return [ + 'top' => $this->top, + 'right' => $this->right, + 'bottom' => $this->bottom, + 'left' => $this->left, + ]; + } +} diff --git a/vendor/endroid/qr-code/src/Label/Margin/MarginInterface.php b/vendor/endroid/qr-code/src/Label/Margin/MarginInterface.php new file mode 100644 index 0000000..bc428bd --- /dev/null +++ b/vendor/endroid/qr-code/src/Label/Margin/MarginInterface.php @@ -0,0 +1,19 @@ + */ + public function toArray(): array; +} diff --git a/vendor/endroid/qr-code/src/Logo/Logo.php b/vendor/endroid/qr-code/src/Logo/Logo.php new file mode 100644 index 0000000..bc4691f --- /dev/null +++ b/vendor/endroid/qr-code/src/Logo/Logo.php @@ -0,0 +1,36 @@ +path; + } + + public function getResizeToWidth(): ?int + { + return $this->resizeToWidth; + } + + public function getResizeToHeight(): ?int + { + return $this->resizeToHeight; + } + + public function getPunchoutBackground(): bool + { + return $this->punchoutBackground; + } +} diff --git a/vendor/endroid/qr-code/src/Logo/LogoInterface.php b/vendor/endroid/qr-code/src/Logo/LogoInterface.php new file mode 100644 index 0000000..13d940c --- /dev/null +++ b/vendor/endroid/qr-code/src/Logo/LogoInterface.php @@ -0,0 +1,16 @@ +> $blockValues */ + public function __construct( + private array $blockValues, + int $size, + int $margin, + RoundBlockSizeMode $roundBlockSizeMode, + ) { + $blockSize = $size / $this->getBlockCount(); + $innerSize = $size; + $outerSize = $size + 2 * $margin; + + switch ($roundBlockSizeMode) { + case RoundBlockSizeMode::Enlarge: + $blockSize = intval(ceil($blockSize)); + $innerSize = intval($blockSize * $this->getBlockCount()); + $outerSize = $innerSize + 2 * $margin; + break; + case RoundBlockSizeMode::Shrink: + $blockSize = intval(floor($blockSize)); + $innerSize = intval($blockSize * $this->getBlockCount()); + $outerSize = $innerSize + 2 * $margin; + break; + case RoundBlockSizeMode::Margin: + $blockSize = intval(floor($blockSize)); + $innerSize = intval($blockSize * $this->getBlockCount()); + break; + } + + if ($blockSize < 1) { + throw new BlockSizeTooSmallException('Too much data: increase image dimensions or lower error correction level'); + } + + $this->blockSize = $blockSize; + $this->innerSize = $innerSize; + $this->outerSize = $outerSize; + $this->marginLeft = intval(($this->outerSize - $this->innerSize) / 2); + $this->marginRight = $this->outerSize - $this->innerSize - $this->marginLeft; + } + + public function getBlockValue(int $rowIndex, int $columnIndex): int + { + return $this->blockValues[$rowIndex][$columnIndex]; + } + + public function getBlockCount(): int + { + return count($this->blockValues[0]); + } + + public function getBlockSize(): float + { + return $this->blockSize; + } + + public function getInnerSize(): int + { + return $this->innerSize; + } + + public function getOuterSize(): int + { + return $this->outerSize; + } + + public function getMarginLeft(): int + { + return $this->marginLeft; + } + + public function getMarginRight(): int + { + return $this->marginRight; + } +} diff --git a/vendor/endroid/qr-code/src/Matrix/MatrixFactoryInterface.php b/vendor/endroid/qr-code/src/Matrix/MatrixFactoryInterface.php new file mode 100644 index 0000000..be501f1 --- /dev/null +++ b/vendor/endroid/qr-code/src/Matrix/MatrixFactoryInterface.php @@ -0,0 +1,12 @@ +data; + } + + public function getEncoding(): EncodingInterface + { + return $this->encoding; + } + + public function getErrorCorrectionLevel(): ErrorCorrectionLevel + { + return $this->errorCorrectionLevel; + } + + public function getSize(): int + { + return $this->size; + } + + public function getMargin(): int + { + return $this->margin; + } + + public function getRoundBlockSizeMode(): RoundBlockSizeMode + { + return $this->roundBlockSizeMode; + } + + public function getForegroundColor(): ColorInterface + { + return $this->foregroundColor; + } + + public function getBackgroundColor(): ColorInterface + { + return $this->backgroundColor; + } +} diff --git a/vendor/endroid/qr-code/src/QrCodeInterface.php b/vendor/endroid/qr-code/src/QrCodeInterface.php new file mode 100644 index 0000000..1a75726 --- /dev/null +++ b/vendor/endroid/qr-code/src/QrCodeInterface.php @@ -0,0 +1,27 @@ +create($qrCode); + } + + public function write(QrCodeInterface $qrCode, ?LogoInterface $logo = null, ?LabelInterface $label = null, array $options = []): ResultInterface + { + if (!extension_loaded('gd')) { + throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly'); + } + + $matrix = $this->getMatrix($qrCode); + + $baseBlockSize = RoundBlockSizeMode::None === $qrCode->getRoundBlockSizeMode() ? 10 : intval($matrix->getBlockSize()); + $baseImage = imagecreatetruecolor($matrix->getBlockCount() * $baseBlockSize, $matrix->getBlockCount() * $baseBlockSize); + + if (!$baseImage) { + throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly'); + } + + /** @var int $foregroundColor */ + $foregroundColor = imagecolorallocatealpha( + $baseImage, + $qrCode->getForegroundColor()->getRed(), + $qrCode->getForegroundColor()->getGreen(), + $qrCode->getForegroundColor()->getBlue(), + $qrCode->getForegroundColor()->getAlpha() + ); + + /** @var int $transparentColor */ + $transparentColor = imagecolorallocatealpha($baseImage, 255, 255, 255, 127); + + imagefill($baseImage, 0, 0, $transparentColor); + + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) { + imagefilledrectangle( + $baseImage, + $columnIndex * $baseBlockSize, + $rowIndex * $baseBlockSize, + ($columnIndex + 1) * $baseBlockSize - 1, + ($rowIndex + 1) * $baseBlockSize - 1, + $foregroundColor + ); + } + } + } + + $targetWidth = $matrix->getOuterSize(); + $targetHeight = $matrix->getOuterSize(); + + if ($label instanceof LabelInterface) { + $labelImageData = LabelImageData::createForLabel($label); + $targetHeight += $labelImageData->getHeight() + $label->getMargin()->getTop() + $label->getMargin()->getBottom(); + } + + $targetImage = imagecreatetruecolor($targetWidth, $targetHeight); + + if (!$targetImage) { + throw new \Exception('Unable to generate image: please check if the GD extension is enabled and configured correctly'); + } + + /** @var int $backgroundColor */ + $backgroundColor = imagecolorallocatealpha( + $targetImage, + $qrCode->getBackgroundColor()->getRed(), + $qrCode->getBackgroundColor()->getGreen(), + $qrCode->getBackgroundColor()->getBlue(), + $qrCode->getBackgroundColor()->getAlpha() + ); + + imagefill($targetImage, 0, 0, $backgroundColor); + + imagecopyresampled( + $targetImage, + $baseImage, + $matrix->getMarginLeft(), + $matrix->getMarginLeft(), + 0, + 0, + $matrix->getInnerSize(), + $matrix->getInnerSize(), + imagesx($baseImage), + imagesy($baseImage) + ); + + if ($qrCode->getBackgroundColor()->getAlpha() > 0) { + imagesavealpha($targetImage, true); + } + + $result = new GdResult($matrix, $targetImage); + + if ($logo instanceof LogoInterface) { + $result = $this->addLogo($logo, $result); + } + + if ($label instanceof LabelInterface) { + $result = $this->addLabel($label, $result); + } + + return $result; + } + + private function addLogo(LogoInterface $logo, GdResult $result): GdResult + { + $logoImageData = LogoImageData::createForLogo($logo); + + if ('image/svg+xml' === $logoImageData->getMimeType()) { + throw new \Exception('PNG Writer does not support SVG logo'); + } + + $targetImage = $result->getImage(); + $matrix = $result->getMatrix(); + + if ($logoImageData->getPunchoutBackground()) { + /** @var int $transparent */ + $transparent = imagecolorallocatealpha($targetImage, 255, 255, 255, 127); + imagealphablending($targetImage, false); + $xOffsetStart = intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2); + $yOffsetStart = intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2); + for ($xOffset = $xOffsetStart; $xOffset < $xOffsetStart + $logoImageData->getWidth(); ++$xOffset) { + for ($yOffset = $yOffsetStart; $yOffset < $yOffsetStart + $logoImageData->getHeight(); ++$yOffset) { + imagesetpixel($targetImage, $xOffset, $yOffset, $transparent); + } + } + } + + imagecopyresampled( + $targetImage, + $logoImageData->getImage(), + intval($matrix->getOuterSize() / 2 - $logoImageData->getWidth() / 2), + intval($matrix->getOuterSize() / 2 - $logoImageData->getHeight() / 2), + 0, + 0, + $logoImageData->getWidth(), + $logoImageData->getHeight(), + imagesx($logoImageData->getImage()), + imagesy($logoImageData->getImage()) + ); + + return new GdResult($matrix, $targetImage); + } + + private function addLabel(LabelInterface $label, GdResult $result): GdResult + { + $targetImage = $result->getImage(); + + $labelImageData = LabelImageData::createForLabel($label); + + /** @var int $textColor */ + $textColor = imagecolorallocatealpha( + $targetImage, + $label->getTextColor()->getRed(), + $label->getTextColor()->getGreen(), + $label->getTextColor()->getBlue(), + $label->getTextColor()->getAlpha() + ); + + $x = intval(imagesx($targetImage) / 2 - $labelImageData->getWidth() / 2); + $y = imagesy($targetImage) - $label->getMargin()->getBottom(); + + if (LabelAlignment::Left === $label->getAlignment()) { + $x = $label->getMargin()->getLeft(); + } elseif (LabelAlignment::Right === $label->getAlignment()) { + $x = imagesx($targetImage) - $labelImageData->getWidth() - $label->getMargin()->getRight(); + } + + imagettftext($targetImage, $label->getFont()->getSize(), 0, $x, $y, $textColor, $label->getFont()->getPath(), $label->getText()); + + return new GdResult($result->getMatrix(), $targetImage); + } + + public function validateResult(ResultInterface $result, string $expectedData): void + { + $string = $result->getString(); + + if (!class_exists(QrReader::class)) { + throw ValidationException::createForMissingPackage('khanamiryan/qrcode-detector-decoder'); + } + + $reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB); + if ($reader->text() !== $expectedData) { + throw ValidationException::createForInvalidData($expectedData, strval($reader->text())); + } + } +} diff --git a/vendor/endroid/qr-code/src/Writer/BinaryWriter.php b/vendor/endroid/qr-code/src/Writer/BinaryWriter.php new file mode 100644 index 0000000..8e0c7e8 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/BinaryWriter.php @@ -0,0 +1,23 @@ +create($qrCode); + + return new BinaryResult($matrix); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/ConsoleWriter.php b/vendor/endroid/qr-code/src/Writer/ConsoleWriter.php new file mode 100644 index 0000000..e3bb7c3 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/ConsoleWriter.php @@ -0,0 +1,23 @@ +create($qrCode); + + return new ConsoleResult($matrix, $qrCode->getForegroundColor(), $qrCode->getBackgroundColor()); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/DebugWriter.php b/vendor/endroid/qr-code/src/Writer/DebugWriter.php new file mode 100644 index 0000000..8910a80 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/DebugWriter.php @@ -0,0 +1,32 @@ +create($qrCode); + + return new DebugResult($matrix, $qrCode, $logo, $label, $options); + } + + public function validateResult(ResultInterface $result, string $expectedData): void + { + if (!$result instanceof DebugResult) { + throw new \Exception('Unable to write logo: instance of DebugResult expected'); + } + + $result->setValidateResult(true); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/EpsWriter.php b/vendor/endroid/qr-code/src/Writer/EpsWriter.php new file mode 100644 index 0000000..2f41967 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/EpsWriter.php @@ -0,0 +1,44 @@ +create($qrCode); + + $lines = [ + '%!PS-Adobe-3.0 EPSF-3.0', + '%%BoundingBox: 0 0 '.$matrix->getOuterSize().' '.$matrix->getOuterSize(), + '/F { rectfill } def', + number_format($qrCode->getBackgroundColor()->getRed() / 100, 2, '.', ',').' '.number_format($qrCode->getBackgroundColor()->getGreen() / 100, 2, '.', ',').' '.number_format($qrCode->getBackgroundColor()->getBlue() / 100, 2, '.', ',').' setrgbcolor', + '0 0 '.$matrix->getOuterSize().' '.$matrix->getOuterSize().' F', + number_format($qrCode->getForegroundColor()->getRed() / 100, 2, '.', ',').' '.number_format($qrCode->getForegroundColor()->getGreen() / 100, 2, '.', ',').' '.number_format($qrCode->getForegroundColor()->getBlue() / 100, 2, '.', ',').' setrgbcolor', + ]; + + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + if (1 === $matrix->getBlockValue($matrix->getBlockCount() - 1 - $rowIndex, $columnIndex)) { + $x = $matrix->getMarginLeft() + $matrix->getBlockSize() * $columnIndex; + $y = $matrix->getMarginLeft() + $matrix->getBlockSize() * $rowIndex; + $lines[] = number_format($x, self::DECIMAL_PRECISION, '.', '').' '.number_format($y, self::DECIMAL_PRECISION, '.', '').' '.number_format($matrix->getBlockSize(), self::DECIMAL_PRECISION, '.', '').' '.number_format($matrix->getBlockSize(), self::DECIMAL_PRECISION, '.', '').' F'; + } + } + } + + return new EpsResult($matrix, $lines); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/GifWriter.php b/vendor/endroid/qr-code/src/Writer/GifWriter.php new file mode 100644 index 0000000..031e02c --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/GifWriter.php @@ -0,0 +1,23 @@ +getMatrix(), $gdResult->getImage()); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/PdfWriter.php b/vendor/endroid/qr-code/src/Writer/PdfWriter.php new file mode 100644 index 0000000..3f0cd73 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/PdfWriter.php @@ -0,0 +1,139 @@ +create($qrCode); + + $unit = 'mm'; + if (isset($options[self::WRITER_OPTION_UNIT])) { + $unit = $options[self::WRITER_OPTION_UNIT]; + } + + $allowedUnits = ['mm', 'pt', 'cm', 'in']; + if (!in_array($unit, $allowedUnits)) { + throw new \Exception(sprintf('PDF Measure unit should be one of [%s]', implode(', ', $allowedUnits))); + } + + $labelSpace = 0; + if ($label instanceof LabelInterface) { + $labelSpace = 30; + } + + if (!class_exists(\FPDF::class)) { + throw new \Exception('Unable to find FPDF: check your installation'); + } + + $foregroundColor = $qrCode->getForegroundColor(); + if ($foregroundColor->getAlpha() > 0) { + throw new \Exception('PDF Writer does not support alpha channels'); + } + $backgroundColor = $qrCode->getBackgroundColor(); + if ($backgroundColor->getAlpha() > 0) { + throw new \Exception('PDF Writer does not support alpha channels'); + } + + if (isset($options[self::WRITER_OPTION_PDF])) { + $fpdf = $options[self::WRITER_OPTION_PDF]; + if (!$fpdf instanceof \FPDF) { + throw new \Exception('pdf option must be an instance of FPDF'); + } + } else { + // @todo Check how to add label height later + $fpdf = new \FPDF('P', $unit, [$matrix->getOuterSize(), $matrix->getOuterSize() + $labelSpace]); + $fpdf->AddPage(); + } + + $x = 0; + if (isset($options[self::WRITER_OPTION_X])) { + $x = $options[self::WRITER_OPTION_X]; + } + $y = 0; + if (isset($options[self::WRITER_OPTION_Y])) { + $y = $options[self::WRITER_OPTION_Y]; + } + + $fpdf->SetFillColor($backgroundColor->getRed(), $backgroundColor->getGreen(), $backgroundColor->getBlue()); + $fpdf->Rect($x, $y, $matrix->getOuterSize(), $matrix->getOuterSize(), 'F'); + $fpdf->SetFillColor($foregroundColor->getRed(), $foregroundColor->getGreen(), $foregroundColor->getBlue()); + + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) { + $fpdf->Rect( + $x + $matrix->getMarginLeft() + ($columnIndex * $matrix->getBlockSize()), + $y + $matrix->getMarginLeft() + ($rowIndex * $matrix->getBlockSize()), + $matrix->getBlockSize(), + $matrix->getBlockSize(), + 'F' + ); + } + } + } + + if ($logo instanceof LogoInterface) { + $this->addLogo($logo, $fpdf, $x, $y, $matrix->getOuterSize()); + } + + if ($label instanceof LabelInterface) { + $fpdf->SetXY($x, $y + $matrix->getOuterSize() + $labelSpace - 25); + $fpdf->SetFont('Helvetica', '', $label->getFont()->getSize()); + $fpdf->Cell($matrix->getOuterSize(), 0, $label->getText(), 0, 0, 'C'); + } + + if (isset($options[self::WRITER_OPTION_LINK])) { + $link = $options[self::WRITER_OPTION_LINK]; + $fpdf->Link($x, $y, $x + $matrix->getOuterSize(), $y + $matrix->getOuterSize(), $link); + } + + return new PdfResult($matrix, $fpdf); + } + + private function addLogo(LogoInterface $logo, \FPDF $fpdf, float $x, float $y, float $size): void + { + $logoPath = $logo->getPath(); + $logoHeight = $logo->getResizeToHeight(); + $logoWidth = $logo->getResizeToWidth(); + + if (null === $logoHeight || null === $logoWidth) { + $imageSize = \getimagesize($logoPath); + if (!$imageSize) { + throw new \Exception(sprintf('Unable to read image size for logo "%s"', $logoPath)); + } + [$logoSourceWidth, $logoSourceHeight] = $imageSize; + + if (null === $logoWidth) { + $logoWidth = (int) $logoSourceWidth; + } + + if (null === $logoHeight) { + $aspectRatio = $logoWidth / $logoSourceWidth; + $logoHeight = (int) ($logoSourceHeight * $aspectRatio); + } + } + + $logoX = $x + $size / 2 - $logoWidth / 2; + $logoY = $y + $size / 2 - $logoHeight / 2; + + $fpdf->Image($logoPath, $logoX, $logoY, $logoWidth, $logoHeight); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/PngWriter.php b/vendor/endroid/qr-code/src/Writer/PngWriter.php new file mode 100644 index 0000000..2bfcd97 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/PngWriter.php @@ -0,0 +1,43 @@ +getBackgroundColor()->getAlpha() > 0 || $qrCode->getForegroundColor()->getAlpha() > 0 => null, + $logo instanceof LogoInterface => null, + default => 16, + }; + } + + /** @var GdResult $gdResult */ + $gdResult = parent::write($qrCode, $logo, $label, $options); + + return new PngResult( + $gdResult->getMatrix(), + $gdResult->getImage(), + $options[self::WRITER_OPTION_COMPRESSION_LEVEL], + $options[self::WRITER_OPTION_NUMBER_OF_COLORS] + ); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php b/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php new file mode 100644 index 0000000..b6547d2 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/AbstractResult.php @@ -0,0 +1,31 @@ +matrix; + } + + public function getDataUri(): string + { + return 'data:'.$this->getMimeType().';base64,'.base64_encode($this->getString()); + } + + public function saveToFile(string $path): void + { + $string = $this->getString(); + file_put_contents($path, $string); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php b/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php new file mode 100644 index 0000000..386fb6a --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/BinaryResult.php @@ -0,0 +1,35 @@ +getMatrix(); + + $binaryString = ''; + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + $binaryString .= $matrix->getBlockValue($rowIndex, $columnIndex); + } + $binaryString .= "\n"; + } + + return $binaryString; + } + + public function getMimeType(): string + { + return 'text/plain'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php b/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php new file mode 100644 index 0000000..d3644db --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/ConsoleResult.php @@ -0,0 +1,69 @@ + ' ', + 1 => "\xe2\x96\x80", + 2 => "\xe2\x96\x84", + 3 => "\xe2\x96\x88", + ]; + + private string $colorEscapeCode; + + public function __construct( + MatrixInterface $matrix, + ColorInterface $foreground, + ColorInterface $background, + ) { + parent::__construct($matrix); + + $this->colorEscapeCode = sprintf( + "\e[38;2;%d;%d;%dm\e[48;2;%d;%d;%dm", + $foreground->getRed(), + $foreground->getGreen(), + $foreground->getBlue(), + $background->getRed(), + $background->getGreen(), + $background->getBlue() + ); + } + + public function getMimeType(): string + { + return 'text/plain'; + } + + public function getString(): string + { + $matrix = $this->getMatrix(); + + $side = $matrix->getBlockCount(); + $marginLeft = $this->colorEscapeCode.self::TWO_BLOCKS[0].self::TWO_BLOCKS[0]; + $marginRight = self::TWO_BLOCKS[0].self::TWO_BLOCKS[0]."\e[0m".PHP_EOL; + $marginVertical = $marginLeft.str_repeat(self::TWO_BLOCKS[0], $side).$marginRight; + + $qrCodeString = $marginVertical; + for ($rowIndex = 0; $rowIndex < $side; $rowIndex += 2) { + $qrCodeString .= $marginLeft; + for ($columnIndex = 0; $columnIndex < $side; ++$columnIndex) { + $combined = $matrix->getBlockValue($rowIndex, $columnIndex); + if ($rowIndex + 1 < $side) { + $combined |= $matrix->getBlockValue($rowIndex + 1, $columnIndex) << 1; + } + $qrCodeString .= self::TWO_BLOCKS[$combined]; + } + $qrCodeString .= $marginRight; + } + $qrCodeString .= $marginVertical; + + return $qrCodeString; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php b/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php new file mode 100644 index 0000000..b632993 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/DebugResult.php @@ -0,0 +1,74 @@ + $options */ + private readonly array $options = [], + ) { + parent::__construct($matrix); + } + + public function setValidateResult(bool $validateResult): void + { + $this->validateResult = $validateResult; + } + + public function getString(): string + { + $debugLines = []; + + $debugLines[] = 'Data: '.$this->qrCode->getData(); + $debugLines[] = 'Encoding: '.$this->qrCode->getEncoding(); + $debugLines[] = 'Error Correction Level: '.get_class($this->qrCode->getErrorCorrectionLevel()); + $debugLines[] = 'Size: '.$this->qrCode->getSize(); + $debugLines[] = 'Margin: '.$this->qrCode->getMargin(); + $debugLines[] = 'Round block size mode: '.get_class($this->qrCode->getRoundBlockSizeMode()); + $debugLines[] = 'Foreground color: ['.implode(', ', $this->qrCode->getForegroundColor()->toArray()).']'; + $debugLines[] = 'Background color: ['.implode(', ', $this->qrCode->getBackgroundColor()->toArray()).']'; + + foreach ($this->options as $key => $value) { + $debugLines[] = 'Writer option: '.$key.': '.$value; + } + + if (isset($this->logo)) { + $debugLines[] = 'Logo path: '.$this->logo->getPath(); + $debugLines[] = 'Logo resize to width: '.$this->logo->getResizeToWidth(); + $debugLines[] = 'Logo resize to height: '.$this->logo->getResizeToHeight(); + $debugLines[] = 'Logo punchout background: '.($this->logo->getPunchoutBackground() ? 'true' : 'false'); + } + + if (isset($this->label)) { + $debugLines[] = 'Label text: '.$this->label->getText(); + $debugLines[] = 'Label font path: '.$this->label->getFont()->getPath(); + $debugLines[] = 'Label font size: '.$this->label->getFont()->getSize(); + $debugLines[] = 'Label alignment: '.get_class($this->label->getAlignment()); + $debugLines[] = 'Label margin: ['.implode(', ', $this->label->getMargin()->toArray()).']'; + $debugLines[] = 'Label text color: ['.implode(', ', $this->label->getTextColor()->toArray()).']'; + } + + $debugLines[] = 'Validate result: '.($this->validateResult ? 'true' : 'false'); + + return implode("\n", $debugLines); + } + + public function getMimeType(): string + { + return 'text/plain'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php b/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php new file mode 100644 index 0000000..d801fd6 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/EpsResult.php @@ -0,0 +1,28 @@ + $lines */ + private readonly array $lines, + ) { + parent::__construct($matrix); + } + + public function getString(): string + { + return implode("\n", $this->lines); + } + + public function getMimeType(): string + { + return 'image/eps'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/GdResult.php b/vendor/endroid/qr-code/src/Writer/Result/GdResult.php new file mode 100644 index 0000000..a58c3e4 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/GdResult.php @@ -0,0 +1,32 @@ +image; + } + + public function getString(): string + { + throw new \Exception('You can only use this method in a concrete implementation'); + } + + public function getMimeType(): string + { + throw new \Exception('You can only use this method in a concrete implementation'); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/GifResult.php b/vendor/endroid/qr-code/src/Writer/Result/GifResult.php new file mode 100644 index 0000000..84b2497 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/GifResult.php @@ -0,0 +1,21 @@ +image); + + return strval(ob_get_clean()); + } + + public function getMimeType(): string + { + return 'image/gif'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php b/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php new file mode 100644 index 0000000..f7746a2 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/PdfResult.php @@ -0,0 +1,32 @@ +fpdf; + } + + public function getString(): string + { + return $this->fpdf->Output('S'); + } + + public function getMimeType(): string + { + return 'application/pdf'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/PngResult.php b/vendor/endroid/qr-code/src/Writer/Result/PngResult.php new file mode 100644 index 0000000..8cdbc53 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/PngResult.php @@ -0,0 +1,35 @@ +numberOfColors) { + imagetruecolortopalette($this->image, false, $this->numberOfColors); + } + imagepng($this->image, quality: $this->quality); + + return strval(ob_get_clean()); + } + + public function getMimeType(): string + { + return 'image/png'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php b/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php new file mode 100644 index 0000000..2cd387e --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/ResultInterface.php @@ -0,0 +1,20 @@ +xml; + } + + public function getString(): string + { + $string = $this->xml->asXML(); + + if (!is_string($string)) { + throw new \Exception('Could not save SVG XML to string'); + } + + if ($this->excludeXmlDeclaration) { + $string = str_replace("\n", '', $string); + } + + return $string; + } + + public function getMimeType(): string + { + return 'image/svg+xml'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/Result/WebPResult.php b/vendor/endroid/qr-code/src/Writer/Result/WebPResult.php new file mode 100644 index 0000000..735f128 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/Result/WebPResult.php @@ -0,0 +1,35 @@ +image, quality: $this->quality); + + return strval(ob_get_clean()); + } + + public function getMimeType(): string + { + return 'image/webp'; + } +} diff --git a/vendor/endroid/qr-code/src/Writer/SvgWriter.php b/vendor/endroid/qr-code/src/Writer/SvgWriter.php new file mode 100644 index 0000000..9001279 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/SvgWriter.php @@ -0,0 +1,174 @@ +create($qrCode); + + $xml = new \SimpleXMLElement(''); + $xml->addAttribute('version', '1.1'); + if (!$options[self::WRITER_OPTION_EXCLUDE_SVG_WIDTH_AND_HEIGHT]) { + $xml->addAttribute('width', $matrix->getOuterSize().'px'); + $xml->addAttribute('height', $matrix->getOuterSize().'px'); + } + $xml->addAttribute('viewBox', '0 0 '.$matrix->getOuterSize().' '.$matrix->getOuterSize()); + + $background = $xml->addChild('rect'); + $background->addAttribute('x', '0'); + $background->addAttribute('y', '0'); + $background->addAttribute('width', strval($matrix->getOuterSize())); + $background->addAttribute('height', strval($matrix->getOuterSize())); + $background->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getBackgroundColor()->getRed(), $qrCode->getBackgroundColor()->getGreen(), $qrCode->getBackgroundColor()->getBlue())); + $background->addAttribute('fill-opacity', strval($qrCode->getBackgroundColor()->getOpacity())); + + if ($options[self::WRITER_OPTION_COMPACT]) { + $this->writePath($xml, $qrCode, $matrix); + } else { + $this->writeBlockDefinitions($xml, $qrCode, $matrix, $options); + } + + $result = new SvgResult($matrix, $xml, boolval($options[self::WRITER_OPTION_EXCLUDE_XML_DECLARATION])); + + if ($logo instanceof LogoInterface) { + $this->addLogo($logo, $result, $options); + } + + return $result; + } + + private function writePath(\SimpleXMLElement $xml, QrCodeInterface $qrCode, MatrixInterface $matrix): void + { + $path = ''; + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + $left = $matrix->getMarginLeft(); + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) { + // When we are at the first column or when the previous column was 0 set new left + if (0 === $columnIndex || 0 === $matrix->getBlockValue($rowIndex, $columnIndex - 1)) { + $left = $matrix->getMarginLeft() + $matrix->getBlockSize() * $columnIndex; + } + // When we are at the + if ($columnIndex === $matrix->getBlockCount() - 1 || 0 === $matrix->getBlockValue($rowIndex, $columnIndex + 1)) { + $top = $matrix->getMarginLeft() + $matrix->getBlockSize() * $rowIndex; + $bottom = $matrix->getMarginLeft() + $matrix->getBlockSize() * ($rowIndex + 1); + $right = $matrix->getMarginLeft() + $matrix->getBlockSize() * ($columnIndex + 1); + $path .= 'M'.$this->formatNumber($left).','.$this->formatNumber($top); + $path .= 'L'.$this->formatNumber($right).','.$this->formatNumber($top); + $path .= 'L'.$this->formatNumber($right).','.$this->formatNumber($bottom); + $path .= 'L'.$this->formatNumber($left).','.$this->formatNumber($bottom).'Z'; + } + } + } + } + + $pathDefinition = $xml->addChild('path'); + $pathDefinition->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getForegroundColor()->getRed(), $qrCode->getForegroundColor()->getGreen(), $qrCode->getForegroundColor()->getBlue())); + $pathDefinition->addAttribute('fill-opacity', strval($qrCode->getForegroundColor()->getOpacity())); + $pathDefinition->addAttribute('d', $path); + } + + /** @param array $options */ + private function writeBlockDefinitions(\SimpleXMLElement $xml, QrCodeInterface $qrCode, MatrixInterface $matrix, array $options): void + { + $xml->addChild('defs'); + + $blockDefinition = $xml->defs->addChild('rect'); + $blockDefinition->addAttribute('id', strval($options[self::WRITER_OPTION_BLOCK_ID])); + $blockDefinition->addAttribute('width', $this->formatNumber($matrix->getBlockSize())); + $blockDefinition->addAttribute('height', $this->formatNumber($matrix->getBlockSize())); + $blockDefinition->addAttribute('fill', '#'.sprintf('%02x%02x%02x', $qrCode->getForegroundColor()->getRed(), $qrCode->getForegroundColor()->getGreen(), $qrCode->getForegroundColor()->getBlue())); + $blockDefinition->addAttribute('fill-opacity', strval($qrCode->getForegroundColor()->getOpacity())); + + for ($rowIndex = 0; $rowIndex < $matrix->getBlockCount(); ++$rowIndex) { + for ($columnIndex = 0; $columnIndex < $matrix->getBlockCount(); ++$columnIndex) { + if (1 === $matrix->getBlockValue($rowIndex, $columnIndex)) { + $block = $xml->addChild('use'); + $block->addAttribute('x', $this->formatNumber($matrix->getMarginLeft() + $matrix->getBlockSize() * $columnIndex)); + $block->addAttribute('y', $this->formatNumber($matrix->getMarginLeft() + $matrix->getBlockSize() * $rowIndex)); + $block->addAttribute('xlink:href', '#'.$options[self::WRITER_OPTION_BLOCK_ID], 'http://www.w3.org/1999/xlink'); + } + } + } + } + + /** @param array $options */ + private function addLogo(LogoInterface $logo, SvgResult $result, array $options): void + { + if ($logo->getPunchoutBackground()) { + throw new \Exception('The SVG writer does not support logo punchout background'); + } + + $logoImageData = LogoImageData::createForLogo($logo); + + if (!isset($options[self::WRITER_OPTION_FORCE_XLINK_HREF])) { + $options[self::WRITER_OPTION_FORCE_XLINK_HREF] = false; + } + + $xml = $result->getXml(); + + /** @var \SimpleXMLElement $xmlAttributes */ + $xmlAttributes = $xml->attributes(); + + $x = intval($xmlAttributes->width) / 2 - $logoImageData->getWidth() / 2; + $y = intval($xmlAttributes->height) / 2 - $logoImageData->getHeight() / 2; + + $imageDefinition = $xml->addChild('image'); + $imageDefinition->addAttribute('x', strval($x)); + $imageDefinition->addAttribute('y', strval($y)); + $imageDefinition->addAttribute('width', strval($logoImageData->getWidth())); + $imageDefinition->addAttribute('height', strval($logoImageData->getHeight())); + $imageDefinition->addAttribute('preserveAspectRatio', 'none'); + + if ($options[self::WRITER_OPTION_FORCE_XLINK_HREF]) { + $imageDefinition->addAttribute('xlink:href', $logoImageData->createDataUri(), 'http://www.w3.org/1999/xlink'); + } else { + $imageDefinition->addAttribute('href', $logoImageData->createDataUri()); + } + } + + private function formatNumber(float $number): string + { + $string = number_format($number, self::DECIMAL_PRECISION, '.', ''); + $string = rtrim($string, '0'); + + return rtrim($string, '.'); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/ValidatingWriterInterface.php b/vendor/endroid/qr-code/src/Writer/ValidatingWriterInterface.php new file mode 100644 index 0000000..4f40048 --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/ValidatingWriterInterface.php @@ -0,0 +1,12 @@ +getMatrix(), $gdResult->getImage(), $options[self::WRITER_OPTION_QUALITY]); + } +} diff --git a/vendor/endroid/qr-code/src/Writer/WriterInterface.php b/vendor/endroid/qr-code/src/Writer/WriterInterface.php new file mode 100644 index 0000000..66b233f --- /dev/null +++ b/vendor/endroid/qr-code/src/Writer/WriterInterface.php @@ -0,0 +1,16 @@ + $options */ + public function write(QrCodeInterface $qrCode, ?LogoInterface $logo = null, ?LabelInterface $label = null, array $options = []): ResultInterface; +} diff --git a/vendor/latte/latte/bin/latte-lint b/vendor/latte/latte/bin/latte-lint new file mode 100644 index 0000000..69e2e47 --- /dev/null +++ b/vendor/latte/latte/bin/latte-lint @@ -0,0 +1,42 @@ +#!/usr/bin/env php +\n"; + exit(1); +} + +if ($debug = in_array('--debug', $argv, true)) { + echo "Debug mode\n"; +} +if ($strict = in_array('--strict', $argv, true)) { + echo "Strict mode\n"; +} + +$path = $argv[1]; + +try { + $linter = new Latte\Tools\Linter(debug: $debug, strict: $strict); + $ok = $linter->scanDirectory($path); + exit($ok ? 0 : 1); + +} catch (Throwable $e) { + fwrite(STDERR, $debug ? "\n$e\n" : "\nError: {$e->getMessage()}\n"); + exit(2); +} diff --git a/vendor/latte/latte/composer.json b/vendor/latte/latte/composer.json new file mode 100644 index 0000000..045f80a --- /dev/null +++ b/vendor/latte/latte/composer.json @@ -0,0 +1,58 @@ +{ + "name": "latte/latte", + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "keywords": ["template", "nette", "security", "engine", "html", "twig", "context-sensitive", "escaping"], + "homepage": "https://latte.nette.org", + "license": ["BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": "8.2 - 8.5", + "ext-json": "*", + "ext-tokenizer": "*" + }, + "require-dev": { + "nette/tester": "^2.5", + "tracy/tracy": "^2.10", + "nette/utils": "^4.0", + "nette/php-generator": "^4.0", + "phpstan/phpstan-nette": "^2.0@stable" + }, + "suggest": { + "ext-iconv": "to use filters |reverse, |substring", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "ext-fileinfo": "to use filter |datastream", + "ext-intl": "to use Latte\\Engine::setLocale()", + "nette/utils": "to use filter |webalize", + "nette/php-generator": "to use tag {templatePrint}" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "autoload": { + "classmap": ["src/"], + "psr-4": { + "Latte\\": "src/Latte" + } + }, + "minimum-stability": "dev", + "bin": ["bin/latte-lint"], + "scripts": { + "phpstan": "phpstan analyse", + "tester": "tester tests -s" + }, + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + } +} diff --git a/vendor/latte/latte/license.md b/vendor/latte/latte/license.md new file mode 100644 index 0000000..cf741bd --- /dev/null +++ b/vendor/latte/latte/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +This software is provided by the copyright holders and contributors "as is" and +any express or implied warranties, including, but not limited to, the implied +warranties of merchantability and fitness for a particular purpose are +disclaimed. In no event shall the copyright owner or contributors be liable for +any direct, indirect, incidental, special, exemplary, or consequential damages +(including, but not limited to, procurement of substitute goods or services; +loss of use, data, or profits; or business interruption) however caused and on +any theory of liability, whether in contract, strict liability, or tort +(including negligence or otherwise) arising in any way out of the use of this +software, even if advised of the possibility of such damage. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/latte/latte/readme.md b/vendor/latte/latte/readme.md new file mode 100644 index 0000000..385d203 --- /dev/null +++ b/vendor/latte/latte/readme.md @@ -0,0 +1,39 @@ +[![Latte](https://github.com/nette/latte/assets/194960/76c098ff-427c-4b30-9676-97e2d8fd4a56)](https://latte.nette.org) + +  + +

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

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

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

+ +  + +Do you like Latte? Are you looking forward to the new features? + +[![Buy me a coffee](https://files.nette.org/icons/donation-3.svg)](https://github.com/sponsors/dg) + +Thank you! diff --git a/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php b/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php new file mode 100644 index 0000000..7a1a607 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/BlueScreenPanel.php @@ -0,0 +1,98 @@ +addPanel(self::renderError(...)); + $blueScreen->addAction(self::renderUnknownMacro(...)); + if ( + version_compare(Tracy\Debugger::VERSION, '2.9.0', '>=') + && version_compare(Tracy\Debugger::VERSION, '3.0', '<') + ) { + Tracy\Debugger::addSourceMapper(self::mapLatteSourceCode(...)); + $blueScreen->addFileGenerator(fn(string $file) => substr($file, -6) === '.latte' + ? "{block content}\n\$END\$" + : null); + } + } + + + public static function renderError(?\Throwable $e): ?array + { + if ($e instanceof Latte\CompileException && $e->sourceName) { + return [ + 'tab' => 'Template', + 'panel' => (preg_match('#\n|\?#', $e->sourceName) + ? '' + : '

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

') + . '
' + . BlueScreen::highlightLine(htmlspecialchars($e->sourceCode, ENT_IGNORE, 'UTF-8'), $e->position->line ?? 0, 15, $e->position->column ?? 0) + . '
', + ]; + } + + return null; + } + + + public static function renderUnknownMacro(?\Throwable $e): ?array + { + if ( + $e instanceof Latte\CompileException + && $e->sourceName + && @is_file($e->sourceName) // @ - may trigger error + && (preg_match('#Unknown tag (\{\w+)\}, did you mean (\{\w+)\}\?#A', $e->getMessage(), $m) + || preg_match('#Unknown attribute (n:\w+), did you mean (n:\w+)\?#A', $e->getMessage(), $m)) + ) { + return [ + 'link' => Helpers::editorUri($e->sourceName, $e->position?->line, 'fix', $m[1], $m[2]), + 'label' => 'fix it', + ]; + } + + return null; + } + + + /** @return array{file: string, line: int, label: string, active: bool} */ + public static function mapLatteSourceCode(string $file, int $line): ?array + { + return ($source = Latte\Helpers::mapCompiledToSource($file, $line)) && @is_file($source['name']) // @ - may trigger error + ? ['file' => $source['name'], 'line' => $source['line'] ?? 0, 'column' => $source['column'] ?? 0, 'label' => 'Latte', 'active' => true] + : null; + } +} diff --git a/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php b/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php new file mode 100644 index 0000000..52e7a9d --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/LattePanel.php @@ -0,0 +1,123 @@ +addPanel(new self($latte, $name)); + } + + + /** @deprecated use TracyExtension see https://bit.ly/46flfDi */ + public function __construct(?Engine $latte = null, ?string $name = null) + { + $this->name = $name; + if ($latte) { + trigger_error('Replace LattePanel with TracyExtension; see https://bit.ly/46flfDi', E_USER_DEPRECATED); + $latte->addExtension( + new class ($this->templates) extends Extension { + public function __construct( + private array &$templates, + ) { + } + + + public function beforeRender(Template $template): void + { + $this->templates[] = $template; + } + }, + ); + } + } + + + public function addTemplate(Template $template): void + { + $this->templates[] = $template; + } + + + /** + * Renders tab. + */ + public function getTab(): ?string + { + if (!$this->templates) { + return null; + } + + return Tracy\Helpers::capture(function () { + $name = $this->name ?? basename(reset($this->templates)->getName()); + require __DIR__ . '/dist/tab.phtml'; + }); + } + + + /** + * Renders panel. + */ + public function getPanel(): string + { + $this->list = []; + $this->buildList($this->templates[0]); + + return Tracy\Helpers::capture(function () { + $list = $this->list; + $dumpParameters = $this->dumpParameters; + require __DIR__ . '/dist/panel.phtml'; + }); + } + + + private function buildList(Template $template, int $depth = 0, int $count = 1): void + { + $this->list[] = (object) [ + 'template' => $template, + 'depth' => $depth, + 'count' => $count, + 'phpFile' => (new \ReflectionObject($template))->getFileName(), + ]; + + $children = $counter = []; + foreach ($this->templates as $t) { + if ($t->getReferringTemplate() === $template) { + $children[$t->getName()] = $t; + @$counter[$t->getName()]++; + } + } + + foreach ($children as $name => $t) { + $this->buildList($t, $depth + 1, $counter[$name]); + } + } +} diff --git a/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php b/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php new file mode 100644 index 0000000..6b1c6bd --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/TracyExtension.php @@ -0,0 +1,37 @@ +panel = new LattePanel(name: $name); + Tracy\Debugger::getBar()->addPanel($this->panel); + } + + + public function beforeRender(Template $template): void + { + $this->panel->addTemplate($template); + } +} diff --git a/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml b/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml new file mode 100644 index 0000000..e5a3e40 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/dist/panel.phtml @@ -0,0 +1,96 @@ + + '#00000052', + 'extends' => '#cd1c1c7d', + 'import' => '#17c35b8f', + 'includeblock' => '#17c35b8f', + 'embed' => '#4f1ccd7d', + 'sandbox' => 'black', +] ?> + + +

Rendered Templates

+ +
+ + + + + + +
+template->getReferenceType()): ?> └  + template->getReferenceType()) ?> + + + template->getName()) ?> + + + php + count > 1 ? $item->count . '×' : '') ?> +
+ +

Parameters

+ +
+ +template->getParameters() as $k => $v): ?> + + + +
+ true]) ?> +
+
+
diff --git a/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml b/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml new file mode 100644 index 0000000..9ccdb86 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/dist/tab.phtml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/vendor/latte/latte/src/Bridges/Tracy/panel.latte b/vendor/latte/latte/src/Bridges/Tracy/panel.latte new file mode 100644 index 0000000..4e83616 --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/panel.latte @@ -0,0 +1,94 @@ +{do $colors = [ + 'include' => '#00000052', + 'extends' => '#cd1c1c7d', + 'import' => '#17c35b8f', + 'includeblock' => '#17c35b8f', + 'embed' => '#4f1ccd7d', + 'sandbox' => 'black', +]} + + + +

Rendered Templates

+ +
+ + {foreach $list as $item} + + + + + + {/foreach} +
+ {if $item->template->getReferenceType()} + └  + {$item->template->getReferenceType()} + {/if} + + {Tracy\Helpers::editorLink($item->template->getName())} + + php + {$item->count > 1 ? $item->count . '×' : ''}
+ + {if $dumpParameters} +

Parameters

+ +
+ + {foreach reset($list)->template->getParameters() as $k => $v} + + + + + {/foreach} +
{$k}{Tracy\Dumper::toHtml($v, [Tracy\Dumper::LIVE => true])}
+
+ {/if} +
diff --git a/vendor/latte/latte/src/Bridges/Tracy/tab.latte b/vendor/latte/latte/src/Bridges/Tracy/tab.latte new file mode 100644 index 0000000..8467aed --- /dev/null +++ b/vendor/latte/latte/src/Bridges/Tracy/tab.latte @@ -0,0 +1,8 @@ + + + + + + {$name} + diff --git a/vendor/latte/latte/src/Latte/Cache.php b/vendor/latte/latte/src/Latte/Cache.php new file mode 100644 index 0000000..a33902a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Cache.php @@ -0,0 +1,142 @@ +generateFilePath($engine, $name); + $signature = $this->autoRefresh + ? hash('xxh128', serialize($this->generateRefreshSignature($engine, $name))) + : null; + $lock = defined('PHP_WINDOWS_VERSION_BUILD') || $signature + ? $this->acquireLock("$file.lock", LOCK_SH) + : null; + + if ( + !($signature && $signature !== stream_get_contents($lock)) + && (@include $file) !== false // @ - file may not exist + ) { + return; + } + + if ($lock) { + flock($lock, LOCK_UN); // release shared lock so we can get exclusive + fseek($lock, 0); + } + + $lock = $this->acquireLock("$file.lock", LOCK_EX); + + // while waiting for exclusive lock, someone might have already created the cache + if (!is_file($file) || ($signature && $signature !== stream_get_contents($lock))) { + $compiled = $engine->compile($name); + if ( + file_put_contents("$file.tmp", $compiled) !== strlen($compiled) + || !rename("$file.tmp", $file) + ) { + @unlink("$file.tmp"); // @ - file may not exist + throw new RuntimeException("Unable to create '$file'."); + } + + fseek($lock, 0); + fwrite($lock, $signature ?? hash('xxh128', serialize($this->generateRefreshSignature($engine, $name)))); + ftruncate($lock, ftell($lock)); + + if (function_exists('opcache_invalidate')) { + @opcache_invalidate($file, true); // @ can be restricted + } + } + + if ((include $file) === false) { + throw new RuntimeException("Unable to load '$file'."); + } + + flock($lock, LOCK_UN); + } + + + /** @return resource */ + private function acquireLock(string $file, int $mode) + { + $dir = dirname($file); + if (!is_dir($dir) && !@mkdir($dir) && !is_dir($dir)) { // @ - dir may already exist + throw new RuntimeException("Unable to create directory '$dir'. " . error_get_last()['message']); + } + + $handle = @fopen($file, 'c+'); // @ is escalated to exception + if (!$handle) { + throw new RuntimeException("Unable to create file '$file'. " . error_get_last()['message']); + } elseif (!@flock($handle, $mode)) { // @ is escalated to exception + throw new RuntimeException('Unable to acquire ' . ($mode & LOCK_EX ? 'exclusive' : 'shared') . " lock on file '$file'. " . error_get_last()['message']); + } + + return $handle; + } + + + /** + * Returns the file path where compiled template will be cached. + * Different configurations produce different file paths. + */ + public function generateFilePath(Engine $engine, string $name): string + { + $base = preg_match('#([/\\\][\w@.-]{3,35}){1,3}$#D', '/' . $name, $m) + ? preg_replace('#[^\w@.-]+#', '-', substr($m[0], 1)) + : ''; + if (!str_ends_with($base, 'latte')) { + $base .= '-latte'; + } + return $this->directory . '/' . $base . '--' . $engine->generateTemplateHash($name) . '.php'; + } + + + public static function isCacheFile(string $file): bool + { + return (bool) preg_match('/latte--\w{10}\.php$/', $file); + } + + + /** + * Returns values used to detect if cached template needs recompilation when autoRefresh is enabled. + * Triggers recompilation when template code, Latte engine, or any extension changes. + */ + protected function generateRefreshSignature(Engine $engine, string $name): array + { + return [ + Engine::Version, + $engine->getLoader()->getContent($name), + array_map( + fn($extension) => filemtime((new \ReflectionObject($extension))->getFileName()), + $engine->getExtensions(), + ), + ]; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Block.php b/vendor/latte/latte/src/Latte/Compiler/Block.php new file mode 100644 index 0000000..ce1d6fe --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Block.php @@ -0,0 +1,41 @@ +name instanceof Scalar\StringNode + && !$this->name instanceof Scalar\IntegerNode; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Escaper.php b/vendor/latte/latte/src/Latte/Compiler/Escaper.php new file mode 100644 index 0000000..e1f7fb2 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Escaper.php @@ -0,0 +1,253 @@ + [ + self::HtmlText => 'HtmlHelpers::escapeText', + self::HtmlAttribute => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::JavaScript => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::Css => 'HtmlHelpers::escapeAttr', + self::HtmlComment => 'HtmlHelpers::escapeComment', + 'xml' => 'XmlHelpers::escapeText', + 'xml/attr' => 'XmlHelpers::escapeAttr', + ], + self::JavaScript => [ + self::HtmlText => 'HtmlHelpers::escapeText', + self::HtmlAttribute => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::JavaScript => 'HtmlHelpers::escapeAttr', + self::HtmlRawText . '/' . self::JavaScript => 'HtmlHelpers::convertJSToRawText', + self::HtmlComment => 'HtmlHelpers::escapeComment', + ], + self::Css => [ + self::HtmlText => 'HtmlHelpers::escapeText', + self::HtmlAttribute => 'HtmlHelpers::escapeAttr', + self::HtmlAttribute . '/' . self::Css => 'HtmlHelpers::escapeAttr', + self::HtmlRawText . '/' . self::Css => 'HtmlHelpers::convertJSToRawText', + self::HtmlComment => 'HtmlHelpers::escapeComment', + ], + self::HtmlText => [ + self::Text => 'HtmlHelpers::convertHtmlToText', + self::HtmlAttribute => 'HtmlHelpers::convertHtmlToAttr', + self::HtmlAttribute . '/' . self::JavaScript => 'HtmlHelpers::convertHtmlToAttr', + self::HtmlAttribute . '/' . self::Css => 'HtmlHelpers::convertHtmlToAttr', + self::HtmlComment => 'HtmlHelpers::escapeComment', + self::HtmlRawText . '/' . self::HtmlText => 'HtmlHelpers::convertHtmlToRawText', + ], + self::HtmlAttribute => [ + self::HtmlText => 'HtmlHelpers::convertAttrToHtml', + ], + ]; + + private string $state = ''; + private string $tag = ''; + private string $subType = ''; + + + public function __construct( + private string $contentType, + ) { + $this->state = in_array($contentType, [ContentType::Html, ContentType::Xml], true) + ? self::HtmlText + : $contentType; + } + + + public function getContentType(): string + { + return $this->contentType; + } + + + public function getState(): string + { + return $this->state; + } + + + public function export(): string + { + return $this->state . ($this->subType ? '/' . $this->subType : ''); + } + + + public function enterContentType(string $type): void + { + $this->contentType = $this->state = $type; + } + + + public function enterHtmlText(ElementNode $el): void + { + if ($el->isRawText()) { + $this->state = self::HtmlRawText; + if ($el->is('script')) { + $type = $el->getAttribute('type'); + $this->subType = $type === true || $type === null + ? self::JavaScript + : HtmlHelpers::classifyScriptType($type); + } elseif ($el->is('style')) { + $this->subType = self::Css; + } + + } else { + $this->state = self::HtmlText; + $this->subType = ''; + } + } + + + public function enterHtmlTag(string $name): void + { + $this->state = self::HtmlTag; + $this->tag = $name; + } + + + public function enterHtmlRaw(string $subType): void + { + $this->state = self::HtmlRawText; + $this->subType = $subType; + } + + + public function enterHtmlAttribute(?string $name = null): void + { + $this->state = self::HtmlAttribute; + $this->subType = ''; + + if ($this->contentType === ContentType::Html && is_string($name)) { + $name = strtolower($name); + if (str_starts_with($name, 'on')) { + $this->subType = self::JavaScript; + } elseif ($name === 'style') { + $this->subType = self::Css; + } + } + } + + + public function enterHtmlBogusTag(): void + { + $this->state = self::HtmlBogusTag; + } + + + public function enterHtmlComment(): void + { + $this->state = self::HtmlComment; + } + + + public function escape(string $str): string + { + return match ($this->contentType) { + ContentType::Html => match ($this->state) { + self::HtmlText => 'LR\HtmlHelpers::escapeText(' . $str . ')', + self::HtmlTag => 'LR\HtmlHelpers::escapeTag(' . $str . ')', + self::HtmlAttribute => match ($this->subType) { + '' => 'LR\HtmlHelpers::escapeAttr(' . $str . ')', + self::JavaScript => 'LR\HtmlHelpers::escapeAttr(LR\Helpers::escapeJs(' . $str . '))', + self::Css => 'LR\HtmlHelpers::escapeAttr(LR\Helpers::escapeCss(' . $str . '))', + }, + self::HtmlComment => 'LR\HtmlHelpers::escapeComment(' . $str . ')', + self::HtmlBogusTag => 'LR\HtmlHelpers::escapeTag(' . $str . ')', + self::HtmlRawText => match ($this->subType) { + self::Text => 'LR\HtmlHelpers::convertJSToRawText(' . $str . ')', // sanitization, escaping is not possible + self::HtmlText => 'LR\HtmlHelpers::escapeRawHtml(' . $str . ')', + self::JavaScript => 'LR\Helpers::escapeJs(' . $str . ')', + self::Css => 'LR\Helpers::escapeCss(' . $str . ')', + }, + default => throw new \LogicException("Unknown context $this->contentType, $this->state."), + }, + ContentType::Xml => match ($this->state) { + self::HtmlText => 'LR\XmlHelpers::escapeText(' . $str . ')', + self::HtmlBogusTag => 'LR\XmlHelpers::escapeTag(' . $str . ')', + self::HtmlAttribute => 'LR\XmlHelpers::escapeAttr(' . $str . ')', + self::HtmlComment => 'LR\HtmlHelpers::escapeComment(' . $str . ')', + self::HtmlTag => 'LR\XmlHelpers::escapeTag(' . $str . ')', + default => throw new \LogicException("Unknown context $this->contentType, $this->state."), + }, + ContentType::JavaScript => 'LR\Helpers::escapeJs(' . $str . ')', + ContentType::Css => 'LR\Helpers::escapeCss(' . $str . ')', + ContentType::ICal => 'LR\Helpers::escapeIcal(' . $str . ')', + ContentType::Text => '($this->filters->escape)(' . $str . ')', + default => throw new \LogicException("Unknown content-type $this->contentType."), + }; + } + + + public function escapeMandatory(string $str, ?Position $position = null): string + { + return match ($this->contentType) { + ContentType::Html => match ($this->state) { + self::HtmlAttribute => "LR\\HtmlHelpers::escapeQuotes($str)", + self::HtmlRawText => match ($this->subType) { + self::HtmlText => 'LR\HtmlHelpers::convertHtmlToRawText(' . $str . ')', + default => "LR\\HtmlHelpers::convertJSToRawText($str)", + }, + self::HtmlComment => throw new Latte\CompileException('Using |noescape is not allowed in this context.', $position), + default => $str, + }, + ContentType::Xml => match ($this->state) { + self::HtmlAttribute => "LR\\HtmlHelpers::escapeQuotes($str)", + self::HtmlComment => throw new Latte\CompileException('Using |noescape is not allowed in this context.', $position), + default => $str, + }, + default => $str, + }; + } + + + public function escapeContent(string $str): string + { + return 'LR\Helpers::convertTo($ʟ_fi, ' + . var_export($this->export(), true) . ', ' + . $str + . ')'; + } + + + public static function getConvertor(string $source, string $dest): ?callable + { + return match (true) { + $source === $dest => Helpers::nop(...), + isset(self::Convertors[$source][$dest]) => 'Latte\Runtime\\' . self::Convertors[$source][$dest], + default => null, + }; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Node.php b/vendor/latte/latte/src/Latte/Compiler/Node.php new file mode 100644 index 0000000..86fc276 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Node.php @@ -0,0 +1,21 @@ + + */ +abstract class Node implements \IteratorAggregate +{ + public ?Position $position = null; + + + abstract public function print(PrintContext $context): string; + + + /** @return \Generator */ + abstract public function &getIterator(): \Generator; +} diff --git a/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php b/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php new file mode 100644 index 0000000..3ad2c27 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/NodeHelpers.php @@ -0,0 +1,129 @@ +traverse($node, enter: function (Node $node) use ($filter, &$found) { + if ($filter($node)) { + $found[] = $node; + } + }); + return $found; + } + + + public static function findFirst(Node $node, callable $filter): ?Node + { + $found = null; + (new NodeTraverser) + ->traverse($node, enter: function (Node $node) use ($filter, &$found) { + if ($filter($node)) { + $found = $node; + return NodeTraverser::StopTraversal; + } + }); + return $found; + } + + + public static function clone(Node $node): Node + { + return (new NodeTraverser) + ->traverse($node, enter: fn(Node $node) => clone $node); + } + + + public static function toValue(ExpressionNode $node, bool $constants = false): mixed + { + if ($node instanceof Scalar\BooleanNode + || $node instanceof Scalar\FloatNode + || $node instanceof Scalar\IntegerNode + || $node instanceof Scalar\StringNode + ) { + return $node->value; + + } elseif ($node instanceof Scalar\NullNode) { + return null; + + } elseif ($node instanceof Expression\ArrayNode) { + $res = []; + foreach ($node->items as $item) { + $value = self::toValue($item->value, $constants); + if ($item->key) { + $key = $item->key instanceof Php\IdentifierNode + ? $item->key->name + : self::toValue($item->key, $constants); + $res[$key] = $value; + + } elseif ($item->unpack) { + $res = array_merge($res, $value); + + } else { + $res[] = $value; + } + } + + return $res; + + } elseif ($node instanceof Expression\ConstantFetchNode && $constants) { + $name = $node->name->toCodeString(); + return defined($name) + ? constant($name) + : throw new \InvalidArgumentException("The constant '$name' is not defined."); + + } elseif ($node instanceof Expression\ClassConstantFetchNode && $constants) { + $class = $node->class instanceof Php\NameNode + ? $node->class->toCodeString() + : self::toValue($node->class, $constants); + $name = $class . '::' . $node->name->name; + return defined($name) + ? constant($name) + : throw new \InvalidArgumentException("The constant '$name' is not defined."); + + } else { + throw new \InvalidArgumentException('The expression cannot be converted to PHP value.'); + } + } + + + public static function toText(?Node $node): ?string + { + if ($node instanceof Nodes\FragmentNode) { + $res = ''; + foreach ($node->children as $child) { + if (($s = self::toText($child)) === null) { + return null; + } + $res .= $s; + } + + return $res; + } + + return match (true) { + $node instanceof Nodes\TextNode => $node->content, + $node instanceof Nodes\NopNode => '', + default => null, + }; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php b/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php new file mode 100644 index 0000000..9650b98 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/NodeTraverser.php @@ -0,0 +1,81 @@ +enter = $enter; + $this->leave = $leave; + $this->stop = false; + return $this->traverseNode($node); + } + + + private function traverseNode(Node $node): ?Node + { + $children = true; + if ($this->enter) { + $res = ($this->enter)($node); + if ($res instanceof Node) { + $node = $res; + + } elseif ($res === self::DontTraverseChildren) { + $children = false; + + } elseif ($res === self::StopTraversal) { + $this->stop = true; + return $node; + + } elseif ($res === self::RemoveNode) { + return null; + } + } + + if ($children) { + foreach ($node as &$subnode) { + $subnode = $this->traverseNode($subnode); + if ($this->stop) { + break; + } + } + } + + if (!$this->stop && $this->leave) { + $res = ($this->leave)($node); + if ($res instanceof Node) { + $node = $res; + + } elseif ($res === self::StopTraversal) { + $this->stop = true; + + } elseif ($res === self::RemoveNode) { + return null; + } + } + + return $node; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php new file mode 100644 index 0000000..ac9cc78 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/AreaNode.php @@ -0,0 +1,17 @@ +print)($context, ...$this->nodes); + } + + + public function &getIterator(): \Generator + { + foreach ($this->nodes as &$node) { + if ($node) { + yield $node; + } + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php new file mode 100644 index 0000000..dedce40 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/FragmentNode.php @@ -0,0 +1,72 @@ +append($child); + } + } + + + public function append(AreaNode $node): static + { + if ($node instanceof self) { + $this->children = array_merge($this->children, $node->children); + } elseif (!$node instanceof NopNode) { + $this->children[] = $node; + } + $this->position ??= $node->position; + return $this; + } + + + public function simplify(bool $allowsNull = true): ?AreaNode + { + return match (true) { + !$this->children => $allowsNull ? null : $this, + count($this->children) === 1 => $this->children[0], + default => $this, + }; + } + + + public function print(PrintContext $context): string + { + $res = ''; + foreach ($this->children as $child) { + $res .= $child->print($context); + } + + return $res; + } + + + public function &getIterator(): \Generator + { + foreach ($this->children as &$item) { + yield $item; + } + Helpers::removeNulls($this->children); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php new file mode 100644 index 0000000..b6cf0ac --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/AttributeNode.php @@ -0,0 +1,57 @@ +name->print($context); + if (!$this->value) { + return $res; + } + + $res .= "echo '=';"; + $quote = $this->quote ?? ($this->value instanceof TextNode ? null : '"'); + $res .= $quote ? 'echo ' . var_export($quote, true) . ';' : ''; + + $escaper = $context->beginEscape(); + $escaper->enterHtmlAttribute(NodeHelpers::toText($this->name)); + $res .= $this->value->print($context); + $context->restoreEscape(); + $res .= $quote ? 'echo ' . var_export($quote, true) . ';' : ''; + return $res; + } + + + public function &getIterator(): \Generator + { + yield $this->name; + if ($this->value) { + yield $this->value; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php new file mode 100644 index 0000000..76c94d0 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/BogusTagNode.php @@ -0,0 +1,46 @@ +openDelimiter, true) . ';'; + $context->beginEscape()->enterHtmlBogusTag(); + $res .= $this->content->print($context); + $context->restoreEscape(); + $res .= 'echo ' . var_export($this->endDelimiter, true) . ';'; + return $res; + } + + + public function &getIterator(): \Generator + { + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php new file mode 100644 index 0000000..8ddca5c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/CommentNode.php @@ -0,0 +1,39 @@ +beginEscape()->enterHtmlComment(); + $content = $this->content->print($context); + $context->restoreEscape(); + return "echo '';"; + } + + + public function &getIterator(): \Generator + { + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php new file mode 100644 index 0000000..f448d91 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ElementNode.php @@ -0,0 +1,124 @@ +attributes = new FragmentNode; + } + + + public function getAttribute(string $name): string|Node|bool|null + { + foreach ($this->attributes->children as $child) { + if ($child instanceof AttributeNode + && $child->name instanceof Nodes\TextNode + && $this->matchesIdentifier($name, $child->name->content) + ) { + return NodeHelpers::toText($child->value) ?? $child->value ?? true; + } elseif ($child instanceof ExpressionAttributeNode + && $this->matchesIdentifier($name, $child->name) + ) { + return true; + } + } + + return null; + } + + + public function is(string $name): bool + { + return $this->matchesIdentifier($this->name, $name); + } + + + private function matchesIdentifier(string $a, string $b): bool + { + return $this->contentType === ContentType::Html + ? strcasecmp($a, $b) === 0 + : $a === $b; + } + + + public function isRawText(): bool + { + return $this->contentType === ContentType::Html + && ($this->is('script') || $this->is('style')); + } + + + public function print(PrintContext $context): string + { + $res = $this->dynamicTag + ? $this->dynamicTag->print($context) + : (new TagNode($this))->print($context, captureEnd: false); + + if ($this->content) { + if ($this->dynamicTag) { + $endTag = '$ʟ_tags[' . ($context->generateId()) . ']'; + $res = "\$ʟ_tag = ''; $res $endTag = \$ʟ_tag;"; + } else { + $endTag = var_export('name . '>', true); + } + + $context->beginEscape()->enterHtmlText($this); + $content = $this->content->print($context); + $context->restoreEscape(); + $res .= $this->breakable + ? 'try { ' . $content . ' } finally { echo ' . $endTag . '; } ' + : $content . ' echo ' . $endTag . ';'; + } + + return $res; + } + + + public function &getIterator(): \Generator + { + if ($this->dynamicTag) { + yield $this->dynamicTag; + } + yield $this->attributes; + if ($this->content) { + yield $this->content; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php new file mode 100644 index 0000000..4e68f48 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/ExpressionAttributeNode.php @@ -0,0 +1,58 @@ +getEscaper()->getContentType() === ContentType::Html) { + $type = $this->modifier->removeFilter('toggle') ? 'bool' : LR\HtmlHelpers::classifyAttributeType($this->name); + $method = 'LR\HtmlHelpers::format' . ucfirst($type) . 'Attribute'; + } else { + $method = 'LR\XmlHelpers::formatAttribute'; + } + return $context->format( + 'echo %raw(%dump, %modify(%node), %dump?) %line;', + $method, + $this->indentation . $this->name, + $this->modifier, + $this->value, + (!$this->modifier->removeFilter('accept') && $context->migrationWarnings) ?: null, + $this->value->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->value; + yield $this->modifier; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php new file mode 100644 index 0000000..28e47d3 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Html/TagNode.php @@ -0,0 +1,72 @@ +element->content; + $context->beginEscape()->enterHtmlTag($this->element->name); + + $res = $this->name + ? $context->format( + <<<'XX' + $ʟ_tmp = LR\%raw::validateTagChange(%node, %dump); + %raw + echo '<', $ʟ_tmp %line; + %node + echo %dump; + XX, + $this->element->contentType === ContentType::Html ? 'HtmlHelpers' : 'XmlHelpers', + $this->name, + $this->element->name, + $captureEnd ? '$ʟ_tag = \'\' . $ʟ_tag;' : '', + $this->element->position, + $this->element->attributes, + $this->element->selfClosing ? '/>' : '>', + ) + : $context->format( + '%raw echo %dump; %node echo %dump;', + $captureEnd ? '$ʟ_tag = ' . $context->encodeString("element->name}>") . ' . $ʟ_tag;' : '', + '<' . $this->element->name, + $this->element->attributes, + $this->element->selfClosing ? '/>' : '>', + ); + + $context->restoreEscape(); + return $res; + } + + + public function &getIterator(): \Generator + { + if ($this->name) { + yield $this->name; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php new file mode 100644 index 0000000..b4b4dc1 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/NopNode.php @@ -0,0 +1,27 @@ +name ? $this->name . ': ' : '') + . ($this->byRef ? '&' : '') + . ($this->unpack ? '...' : '') + . $this->value->print($context); + } + + + public function toArrayItem(): ArrayItemNode + { + return new ArrayItemNode($this->value, $this->name, $this->byRef, $this->unpack, $this->position); + } + + + public function &getIterator(): \Generator + { + if ($this->name) { + yield $this->name; + } + yield $this->value; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php new file mode 100644 index 0000000..60d7c3a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ArrayItemNode.php @@ -0,0 +1,62 @@ +key instanceof ExpressionNode => $this->key->print($context) . ' => ', + $this->key instanceof IdentifierNode => $context->encodeString($this->key->name) . ' => ', + $this->key === null => '', + }; + return $key + . ($this->byRef ? '&' : '') + . ($this->unpack ? '...' : '') + . $this->value->print($context); + } + + + public function toArgument(): ArgumentNode + { + $key = match (true) { + $this->key instanceof Scalar\StringNode => new IdentifierNode($this->key->value), + $this->key instanceof IdentifierNode => $this->key, + $this->key === null => null, + default => throw new \InvalidArgumentException('The expression used in the key cannot be converted to an argument.'), + }; + return new ArgumentNode($this->value, $this->byRef, $this->unpack, $key, $this->position); + } + + + public function &getIterator(): \Generator + { + if ($this->key) { + yield $this->key; + } + yield $this->value; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php new file mode 100644 index 0000000..bbd02f1 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ClosureUseNode.php @@ -0,0 +1,38 @@ +byRef ? '&' : '') . $this->var->print($context); + } + + + public function &getIterator(): \Generator + { + yield $this->var; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php new file mode 100644 index 0000000..b6de67a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ComplexTypeNode.php @@ -0,0 +1,17 @@ +dereferenceExpr($this->expr) + . '[' . ($this->index !== null ? $this->index->print($context) : '') . ']'; + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + if ($this->index) { + yield $this->index; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php new file mode 100644 index 0000000..a0068a8 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ArrayNode.php @@ -0,0 +1,51 @@ + */ + public array $items = [], + public ?Position $position = null, + ) { + (function (ArrayItemNode ...$args) {})(...$items); + } + + + /** @return ArgumentNode[] */ + public function toArguments(): array + { + return array_map(fn(ArrayItemNode $item) => $item->toArgument(), $this->items); + } + + + public function print(PrintContext $context): string + { + return '[' . $context->implode($this->items) . ']'; + } + + + public function &getIterator(): \Generator + { + foreach ($this->items as &$item) { + yield $item; + } + Helpers::removeNulls($this->items); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php new file mode 100644 index 0000000..87f6bfb --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignNode.php @@ -0,0 +1,65 @@ +validate(); + } + + + public function print(PrintContext $context): string + { + $this->validate(); + return $context->parenthesize($this, $this->var, self::AssocLeft) + . ($this->byRef ? ' = &' : ' = ') + . $context->parenthesize($this, $this->expr, self::AssocRight); + } + + + public function getOperatorPrecedence(): array + { + return self::Precedence; + } + + + public function validate(): void + { + if ($this->var instanceof ExpressionNode && !$this->var->isWritable()) { + throw new CompileException('Cannot write to the expression: ' . $this->var->print(new PrintContext), $this->var->position); + } elseif ($this->byRef && !$this->expr->isWritable()) { + throw new CompileException('Cannot take reference to the expression: ' . $this->expr->print(new PrintContext), $this->expr->position); + } + } + + + public function &getIterator(): \Generator + { + yield $this->var; + yield $this->expr; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php new file mode 100644 index 0000000..bfaff9b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AssignOpNode.php @@ -0,0 +1,66 @@ +>', '**', '??']; + + + public function __construct( + public ExpressionNode $var, + public string $operator, + public ExpressionNode $expr, + public ?Position $position = null, + ) { + if (!in_array($this->operator, self::Ops, true)) { + throw new \InvalidArgumentException("Unexpected operator '$this->operator'"); + } + $this->validate(); + } + + + public function print(PrintContext $context): string + { + $this->validate(); + return $context->parenthesize($this, $this->var, self::AssocLeft) + . ' ' . $this->operator . '= ' + . $context->parenthesize($this, $this->expr, self::AssocRight); + } + + + public function getOperatorPrecedence(): array + { + return AssignNode::Precedence; + } + + + public function validate(): void + { + if (!$this->var->isWritable()) { + throw new CompileException('Cannot write to the expression: ' . $this->var->print(new PrintContext), $this->var->position); + } + } + + + public function &getIterator(): \Generator + { + yield $this->var; + yield $this->expr; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php new file mode 100644 index 0000000..75c7b19 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/AuxiliaryNode.php @@ -0,0 +1,42 @@ +print)($context, ...$this->nodes); + } + + + public function &getIterator(): \Generator + { + foreach ($this->nodes as &$node) { + if ($node) { + yield $node; + } + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php new file mode 100644 index 0000000..9b0008a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/BinaryOpNode.php @@ -0,0 +1,93 @@ +>', '**', + '==', '!=', '===', '!==', '<=>', '<', '<=', '>', '>=', '??', '|>']; + + + public function __construct( + public ExpressionNode $left, + public string $operator, + public ExpressionNode $right, + public ?Position $position = null, + ) { + if (!in_array(strtolower($this->operator), self::Ops, true)) { + throw new \InvalidArgumentException("Unexpected operator '$this->operator'"); + } + } + + + /** + * Creates nested BinaryOp nodes from a list of expressions. + */ + public static function nest(string $operator, ExpressionNode ...$exprs): ExpressionNode + { + $count = count($exprs); + if ($count < 2) { + return $exprs[0]; + } + + $last = $exprs[0]; + for ($i = 1; $i < $count; $i++) { + $last = new static($last, $operator, $exprs[$i]); + } + + return $last; + } + + + public function print(PrintContext $context): string + { + return $context->parenthesize($this, $this->left, self::AssocLeft) + . ' ' . $this->operator . ' ' + . $context->parenthesize($this, $this->right, self::AssocRight); + } + + + public function getOperatorPrecedence(): array + { + return match (strtolower($this->operator)) { + '**' => [250, self::AssocRight], + '*', '/', '%' => [210, self::AssocLeft], + '+', '-' => [200, self::AssocLeft], + '<<', '>>' => [190, self::AssocLeft], + '.' => [185, self::AssocLeft], + '|>' => [183, self::AssocLeft], + '<', '<=', '>', '>=', '<=>' => [180, self::AssocNone], + '==', '!=', '===', '!==' => [170, self::AssocNone], + '&' => [160, self::AssocLeft], + '^' => [150, self::AssocLeft], + '|' => [140, self::AssocLeft], + '&&' => [130, self::AssocLeft], + '||' => [120, self::AssocLeft], + '??' => [110, self::AssocRight], + 'and' => [50, self::AssocLeft], + 'xor' => [40, self::AssocLeft], + 'or' => [30, self::AssocLeft], + }; + } + + + public function &getIterator(): \Generator + { + yield $this->left; + yield $this->right; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php new file mode 100644 index 0000000..5e3926e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CastNode.php @@ -0,0 +1,50 @@ + 1, 'float' => 1, 'string' => 1, 'array' => 1, 'object' => 1, 'bool' => 1]; + + + public function __construct( + public string $type, + public ExpressionNode $expr, + public ?Position $position = null, + ) { + if (!isset(self::Types[strtolower($this->type)])) { + throw new \InvalidArgumentException("Unexpected type '$this->type'"); + } + } + + + public function print(PrintContext $context): string + { + return '(' . $this->type . ') ' . $context->parenthesize($this, $this->expr, self::AssocRight); + } + + + public function getOperatorPrecedence(): array + { + return [240, self::AssocRight]; + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php new file mode 100644 index 0000000..750f03d --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClassConstantFetchNode.php @@ -0,0 +1,42 @@ +dereferenceExpr($this->class) + . '::' + . $context->objectProperty($this->name); + } + + + public function &getIterator(): \Generator + { + yield $this->class; + yield $this->name; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php new file mode 100644 index 0000000..ff24050 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/CloneNode.php @@ -0,0 +1,43 @@ +expr->print($context); + } + + + public function getOperatorPrecedence(): array + { + return [270, self::AssocNone]; + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php new file mode 100644 index 0000000..eb5423c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ClosureNode.php @@ -0,0 +1,77 @@ +expr; + foreach ($this->uses as $use) { + $arrow = $arrow && !$use->byRef; + } + + return $arrow + ? 'fn' . ($this->byRef ? '&' : '') + . '(' . $context->implode($this->params) . ')' + . ($this->returnType !== null ? ': ' . $this->returnType->print($context) : '') + . ' => ' + . $this->expr->print($context) + : 'function ' . ($this->byRef ? '&' : '') + . '(' . $context->implode($this->params) . ')' + . (!empty($this->uses) ? ' use (' . $context->implode($this->uses) . ')' : '') + . ($this->returnType !== null ? ' : ' . $this->returnType->print($context) : '') + . ($this->expr ? ' { return ' . $this->expr->print($context) . '; }' : ' {}'); + } + + + public function &getIterator(): \Generator + { + foreach ($this->params as &$item) { + yield $item; + } + Helpers::removeNulls($this->params); + + foreach ($this->uses as &$item) { + yield $item; + } + Helpers::removeNulls($this->uses); + + if ($this->returnType) { + yield $this->returnType; + } + if ($this->expr) { + yield $this->expr; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php new file mode 100644 index 0000000..bf3af62 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/ConstantFetchNode.php @@ -0,0 +1,45 @@ +name->kind === NameNode::KindNormal) { + return match ((string) $this->name) { + '__LINE__' => (string) $this->position->line, + '__FILE__' => '(is_file($this->getName()) ? $this->getName() : null)', + '__DIR__' => '(is_file($this->getName()) ? dirname($this->getName()) : null)', + default => $this->name->print($context), + }; + } + return $this->name->print($context); + } + + + public function &getIterator(): \Generator + { + yield $this->name; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php new file mode 100644 index 0000000..ee25e35 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/EmptyNode.php @@ -0,0 +1,36 @@ +expr->print($context) . ')'; + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php new file mode 100644 index 0000000..855bdac --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FilterCallNode.php @@ -0,0 +1,44 @@ +expr) { + array_unshift($filters, $node->filter); + } + + return Php\FilterNode::printSimple($context, $filters, $node->print($context)); + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + yield $this->filter; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php new file mode 100644 index 0000000..b91baeb --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/FunctionCallNode.php @@ -0,0 +1,53 @@ + */ + public array $args = [], + public ?Position $position = null, + ) { + (function (Php\ArgumentNode|Php\VariadicPlaceholderNode ...$args) {})(...$args); + } + + + public function isPartialFunction(): bool + { + return ($this->args[0] ?? null) instanceof Php\VariadicPlaceholderNode; + } + + + public function print(PrintContext $context): string + { + return $context->callExpr($this->name) + . '(' . $context->implode($this->args) . ')'; + } + + + public function &getIterator(): \Generator + { + yield $this->name; + foreach ($this->args as &$item) { + yield $item; + } + Helpers::removeNulls($this->args); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php new file mode 100644 index 0000000..dfa1871 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InNode.php @@ -0,0 +1,42 @@ +needle->print($context) + . ', ' + . $this->haystack->print($context) + . ', true)'; + } + + + public function &getIterator(): \Generator + { + yield $this->needle; + yield $this->haystack; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php new file mode 100644 index 0000000..46aa77e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/InstanceofNode.php @@ -0,0 +1,48 @@ +parenthesize($this, $this->expr, self::AssocLeft) + . ' instanceof ' + . $context->dereferenceExpr($this->class); + } + + + public function getOperatorPrecedence(): array + { + return [230, self::AssocNone]; + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + yield $this->class; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php new file mode 100644 index 0000000..4b44eb4 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/IssetNode.php @@ -0,0 +1,56 @@ +validate(); + } + + + public function print(PrintContext $context): string + { + $this->validate(); + return 'isset(' . $context->implode($this->vars) . ')'; + } + + + public function validate(): void + { + foreach ($this->vars as $var) { + if (!$var instanceof ExpressionNode) { + throw new \TypeError('Variable must be ExpressionNode, ' . get_debug_type($var) . ' given.'); + } elseif (!$var->isVariable()) { + throw new CompileException('Cannot use isset() on expression: ' . $var->print(new PrintContext), $var->position); + } + } + } + + + public function &getIterator(): \Generator + { + foreach ($this->vars as &$item) { + yield $item; + } + Helpers::removeNulls($this->vars); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php new file mode 100644 index 0000000..58f1e7e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MatchNode.php @@ -0,0 +1,51 @@ +cond->print($context) . ') {'; + foreach ($this->arms as $node) { + $res .= "\n" . $node->print($context) . ','; + } + + $res .= "\n}"; + return $res; + } + + + public function &getIterator(): \Generator + { + yield $this->cond; + foreach ($this->arms as &$item) { + yield $item; + } + Helpers::removeNulls($this->arms); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php new file mode 100644 index 0000000..83e197c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/MethodCallNode.php @@ -0,0 +1,62 @@ + */ + public array $args = [], + public bool $nullsafe = false, + public ?Position $position = null, + ) { + (function (Php\ArgumentNode|Php\VariadicPlaceholderNode ...$args) {})(...$args); + } + + + public function isPartialFunction(): bool + { + return ($this->args[0] ?? null) instanceof Php\VariadicPlaceholderNode; + } + + + public function print(PrintContext $context): string + { + if ($this->nullsafe && $this->isPartialFunction()) { + throw new CompileException('Cannot combine nullsafe operator with Closure creation', $this->position); + } + return $context->dereferenceExpr($this->object) + . ($this->nullsafe ? '?->' : '->') + . $context->objectProperty($this->name) + . '(' . $context->implode($this->args) . ')'; + } + + + public function &getIterator(): \Generator + { + yield $this->object; + yield $this->name; + foreach ($this->args as &$item) { + yield $item; + } + Helpers::removeNulls($this->args); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php new file mode 100644 index 0000000..b7a73f9 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/NewNode.php @@ -0,0 +1,54 @@ +dereferenceExpr($this->class) + . ($this->args ? '(' . $context->implode($this->args) . ')' : ''); + } + + + public function getOperatorPrecedence(): array + { + return [270, self::AssocNone]; + } + + + public function &getIterator(): \Generator + { + yield $this->class; + foreach ($this->args as &$item) { + yield $item; + } + Helpers::removeNulls($this->args); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php new file mode 100644 index 0000000..ec3fe31 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PostOpNode.php @@ -0,0 +1,61 @@ + 1, '--' => 1]; + + + public function __construct( + public ExpressionNode $var, + public string $operator, + public ?Position $position = null, + ) { + if (!isset(self::Ops[$this->operator])) { + throw new \InvalidArgumentException("Unexpected operator '$this->operator'"); + } + $this->validate(); + } + + + public function print(PrintContext $context): string + { + $this->validate(); + return $context->parenthesize($this, $this->var, self::AssocLeft) . $this->operator; + } + + + public function getOperatorPrecedence(): array + { + return [240, self::AssocLeft]; + } + + + public function validate(): void + { + if (!$this->var->isWritable()) { + throw new CompileException('Cannot write to the expression: ' . $this->var->print(new PrintContext), $this->var->position); + } + } + + + public function &getIterator(): \Generator + { + yield $this->var; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php new file mode 100644 index 0000000..d671295 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PreOpNode.php @@ -0,0 +1,61 @@ + 1, '--' => 1]; + + + public function __construct( + public ExpressionNode $var, + public string $operator, + public ?Position $position = null, + ) { + if (!isset(self::Ops[$this->operator])) { + throw new \InvalidArgumentException("Unexpected operator '$this->operator'"); + } + $this->validate(); + } + + + public function print(PrintContext $context): string + { + $this->validate(); + return $this->operator . $context->parenthesize($this, $this->var, self::AssocRight); + } + + + public function getOperatorPrecedence(): array + { + return [240, self::AssocRight]; + } + + + public function validate(): void + { + if (!$this->var->isWritable()) { + throw new CompileException('Cannot write to the expression: ' . $this->var->print(new PrintContext), $this->var->position); + } + } + + + public function &getIterator(): \Generator + { + yield $this->var; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php new file mode 100644 index 0000000..9b2a731 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/PropertyFetchNode.php @@ -0,0 +1,42 @@ +dereferenceExpr($this->object) + . ($this->nullsafe ? '?->' : '->') + . $context->objectProperty($this->name); + } + + + public function &getIterator(): \Generator + { + yield $this->object; + yield $this->name; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php new file mode 100644 index 0000000..27380c2 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticMethodCallNode.php @@ -0,0 +1,63 @@ + */ + public array $args = [], + public ?Position $position = null, + ) { + (function (Php\ArgumentNode|Php\VariadicPlaceholderNode ...$args) {})(...$args); + } + + + public function isPartialFunction(): bool + { + return ($this->args[0] ?? null) instanceof Php\VariadicPlaceholderNode; + } + + + public function print(PrintContext $context): string + { + $name = match (true) { + $this->name instanceof VariableNode => $this->name->print($context), + $this->name instanceof ExpressionNode => '{' . $this->name->print($context) . '}', + default => $this->name, + }; + return $context->dereferenceExpr($this->class) + . '::' + . $name + . '(' . $context->implode($this->args) . ')'; + } + + + public function &getIterator(): \Generator + { + yield $this->class; + yield $this->name; + foreach ($this->args as &$item) { + yield $item; + } + Helpers::removeNulls($this->args); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php new file mode 100644 index 0000000..63a3fe7 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/StaticPropertyFetchNode.php @@ -0,0 +1,42 @@ +dereferenceExpr($this->class) + . '::$' + . $context->objectProperty($this->name); + } + + + public function &getIterator(): \Generator + { + yield $this->class; + yield $this->name; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php new file mode 100644 index 0000000..6e87e2a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/TemporaryNode.php @@ -0,0 +1,38 @@ +parenthesize($this, $this->cond, self::AssocLeft) + . ($this->if ? ' ? ' . $this->if->print($context) . ' : ' : ' ?: ') + . $context->parenthesize($this, $this->else ?? new NullNode, self::AssocRight); + } + + + public function getOperatorPrecedence(): array + { + return [100, self::AssocNone]; + } + + + public function &getIterator(): \Generator + { + yield $this->cond; + if ($this->if) { + yield $this->if; + } + if ($this->else) { + yield $this->else; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php new file mode 100644 index 0000000..dabe42b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/UnaryOpNode.php @@ -0,0 +1,54 @@ + 1, '-' => 1, '~' => 1, '@' => 1, '!' => 1]; + + + public function __construct( + public ExpressionNode $expr, + public string $operator, + public ?Position $position = null, + ) { + if (!isset(self::Ops[$this->operator])) { + throw new \InvalidArgumentException("Unexpected operator '$this->operator'"); + } + } + + + public function print(PrintContext $context): string + { + $pos = $this->expr instanceof self || $this->expr instanceof PreOpNode ? self::AssocLeft : self::AssocRight; // Enforce -(-$expr) instead of --$expr + return $this->operator . $context->parenthesize($this, $this->expr, $pos); + } + + + public function getOperatorPrecedence(): array + { + return match ($this->operator) { + '+', '-', '~', '@' => [240, self::AssocRight], + '!' => [220, self::AssocRight], + }; + } + + + public function &getIterator(): \Generator + { + yield $this->expr; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php new file mode 100644 index 0000000..47e02c6 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Expression/VariableNode.php @@ -0,0 +1,40 @@ +name instanceof ExpressionNode + ? '${' . $this->name->print($context) . '}' + : '$' . $this->name; + } + + + public function &getIterator(): \Generator + { + if ($this->name instanceof ExpressionNode) { + yield $this->name; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php new file mode 100644 index 0000000..e8d4f53 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ExpressionNode.php @@ -0,0 +1,41 @@ +nullsafe) + || $this instanceof Expression\StaticPropertyFetchNode + || $this instanceof Expression\VariableNode; + } + + + public function isVariable(): bool + { + return $this instanceof Expression\ArrayAccessNode + || $this instanceof Expression\PropertyFetchNode + || $this instanceof Expression\StaticPropertyFetchNode + || $this instanceof Expression\VariableNode; + } + + + public function isCall(): bool + { + return $this instanceof Expression\FunctionCallNode + || $this instanceof Expression\MethodCallNode + || $this instanceof Expression\StaticMethodCallNode; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php new file mode 100644 index 0000000..7ec0dde --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/FilterNode.php @@ -0,0 +1,86 @@ +name === 'escape') { + throw new CompileException("Filter 'escape' is not allowed.", $position); + } + (function (ArgumentNode ...$args) {})(...$args); + } + + + public function print(PrintContext $context): string + { + throw new \LogicException('Cannot directly print FilterNode'); + } + + + /** @param self[] $filters */ + public static function printSimple(PrintContext $context, array $filters, string $expr): string + { + $nullsafe = false; + $chain = $expr; + $tmp = '$ʟ_tmp'; + foreach ($filters as $filter) { + if ($filter->nullsafe) { + $expr = $nullsafe ? "(($tmp = $expr) === null ? null : $chain)" : $chain; + $chain = $tmp; + $nullsafe = true; + } + + $chain = '($this->filters->' . $context->objectProperty($filter->name) . ')(' + . $chain + . ($filter->args ? ', ' . $context->implode($filter->args) : '') + . ')'; + } + + return $nullsafe ? "(($tmp = $expr) === null ? null : $chain)" : $chain; + } + + + public function printContentAware(PrintContext $context, string $expr): string + { + if ($this->nullsafe) { + throw new CompileException('Content-aware filter cannot be nullsafe.', $this->position); + } + return '$this->filters->filterContent(' + . $context->encodeString($this->name->name) + . ', $ʟ_fi, ' + . $expr + . ($this->args ? ', ' . $context->implode($this->args) : '') + . ')'; + } + + + public function &getIterator(): \Generator + { + yield $this->name; + foreach ($this->args as &$item) { + yield $item; + } + Helpers::removeNulls($this->args); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php new file mode 100644 index 0000000..539fed3 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/IdentifierNode.php @@ -0,0 +1,42 @@ +name; + } + + + public function print(PrintContext $context): string + { + return $this->name; + } + + + public function &getIterator(): \Generator + { + false && yield; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php new file mode 100644 index 0000000..c662864 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/InterpolatedStringPartNode.php @@ -0,0 +1,36 @@ + */ + public array $types, + public ?Position $position = null, + ) { + (function (IdentifierNode|NameNode ...$args) {})(...$types); + } + + + public function print(PrintContext $context): string + { + return $context->implode($this->types, '&'); + } + + + public function &getIterator(): \Generator + { + foreach ($this->types as &$item) { + yield $item; + } + Helpers::removeNulls($this->types); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php new file mode 100644 index 0000000..0352824 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListItemNode.php @@ -0,0 +1,48 @@ +key instanceof ExpressionNode => $this->key->print($context) . ' => ', + $this->key instanceof IdentifierNode => $context->encodeString($this->key->name) . ' => ', + $this->key === null => '', + }; + return $key + . ($this->byRef ? '&' : '') + . $this->value->print($context); + } + + + public function &getIterator(): \Generator + { + if ($this->key) { + yield $this->key; + } + yield $this->value; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php new file mode 100644 index 0000000..02c08b8 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ListNode.php @@ -0,0 +1,56 @@ + */ + public array $items = [], + public ?Position $position = null, + ) { + $this->validate(); + } + + + public function print(PrintContext $context): string + { + $this->validate(); + return '[' . $context->implode($this->items) . ']'; + } + + + public function validate(): void + { + foreach ($this->items as $item) { + if ($item !== null && !$item instanceof ListItemNode) { + throw new \TypeError('Item must be null or ListItemNode, ' . get_debug_type($item) . ' given.'); + } elseif ($item?->value instanceof ExpressionNode && !$item->value->isWritable()) { + throw new CompileException('Cannot write to the expression: ' . $item->value->print(new PrintContext), $item->value->position); + } + } + } + + + public function &getIterator(): \Generator + { + foreach ($this->items as &$item) { + if ($item) { + yield $item; + } + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php new file mode 100644 index 0000000..34311c6 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/MatchArmNode.php @@ -0,0 +1,47 @@ +conds ? $context->implode($this->conds) : 'default') + . ' => ' + . $this->body->print($context); + } + + + public function &getIterator(): \Generator + { + if ($this->conds) { + foreach ($this->conds as &$item) { + yield $item; + } + Helpers::removeNulls($this->conds); + } + yield $this->body; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php new file mode 100644 index 0000000..b47c8f8 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ModifierNode.php @@ -0,0 +1,94 @@ +filters as $filter) { + if ($filter->name->name === $name) { + return true; + } + } + + return false; + } + + + public function removeFilter(string $name): ?FilterNode + { + foreach ($this->filters as $i => $filter) { + if ($filter->name->name === $name) { + return array_splice($this->filters, $i, 1)[0]; + } + } + + return null; + } + + + public function print(PrintContext $context): string + { + throw new \LogicException('Cannot directly print ModifierNode'); + } + + + public function printSimple(PrintContext $context, string $expr): string + { + $expr = FilterNode::printSimple($context, $this->filters, $expr); + + $escaper = $context->getEscaper(); + return $this->escape + ? $escaper->escape($expr) + : $escaper->escapeMandatory($expr, $this->position); + } + + + public function printContentAware(PrintContext $context, string $expr): string + { + foreach ($this->filters as $filter) { + $expr = $filter->printContentAware($context, $expr); + } + + return $this->escape + ? $context->getEscaper()->escapeContent($expr) + : $expr; + } + + + public function &getIterator(): \Generator + { + foreach ($this->filters as &$filter) { + yield $filter; + } + Helpers::removeNulls($this->filters); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php new file mode 100644 index 0000000..52a9e9d --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NameNode.php @@ -0,0 +1,89 @@ +kind = self::KindFullyQualified; + $this->name = substr($name, 1); + } else { + if ($kind === -1 && !str_starts_with($name, '__')) { + trigger_error("Using unqualified constant '$name' is deprecated. Use '\\$name' with a leading backslash $position", E_USER_DEPRECATED); + } + $this->kind = self::KindNormal; + } + } + + + public function isKeyword(): bool + { + static $keywords; + $keywords ??= array_flip([ // https://www.php.net/manual/en/reserved.keywords.php + '__halt_compiler', '__class__', '__dir__', '__file__', '__function__', '__line__', '__method__', '__namespace__', '__trait__', + 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'const', 'continue', 'declare', + 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', + 'endwhile', 'eval', 'exit', 'extends', 'final', 'finally', 'fn', 'for', 'foreach', 'function', 'global', 'goto', 'if', + 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'match', 'namespace', + 'new', 'or', 'print', 'private', 'protected', 'public', 'readonly', 'require', 'require_once', 'return', 'static', + 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', 'yield', + 'parent', 'self', 'mixed', 'void', 'enum', // extra + ]); + return isset($keywords[strtolower($this->name)]); + } + + + public function print(PrintContext $context): string + { + return $this->toCodeString(); + } + + + public function __toString(): string + { + return $this->name; + } + + + public function toCodeString(): string + { + $prefix = match ($this->kind) { + self::KindNormal => $this->isKeyword() ? 'namespace\\' : '', + self::KindFullyQualified => '\\', + }; + return $prefix . $this->name; + } + + + public function &getIterator(): \Generator + { + false && yield; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php new file mode 100644 index 0000000..4eec7b5 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/NullableTypeNode.php @@ -0,0 +1,35 @@ +type->print($context); + } + + + public function &getIterator(): \Generator + { + yield $this->type; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php new file mode 100644 index 0000000..d1bd16b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/OperatorNode.php @@ -0,0 +1,29 @@ +type ? $this->type->print($context) . ' ' : '') + . ($this->byRef ? '&' : '') + . ($this->variadic ? '...' : '') + . $this->var->print($context) + . ($this->default ? ' = ' . $this->default->print($context) : ''); + } + + + public function &getIterator(): \Generator + { + if ($this->type) { + yield $this->type; + } + yield $this->var; + if ($this->default) { + yield $this->default; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php new file mode 100644 index 0000000..1a2b124 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/BooleanNode.php @@ -0,0 +1,30 @@ +value ? 'true' : 'false'; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php new file mode 100644 index 0000000..c803617 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/FloatNode.php @@ -0,0 +1,65 @@ +value)) { + if ($this->value === INF) { + return '\INF'; + } elseif ($this->value === -INF) { + return '-\INF'; + } else { + return '\NAN'; + } + } + + // Try to find a short full-precision representation + $stringValue = sprintf('%.16G', $this->value); + if ($this->value !== (float) $stringValue) { + $stringValue = sprintf('%.17G', $this->value); + } + + // %G is locale dependent and there exists no locale-independent alternative. We don't want + // mess with switching locales here, so let's assume that a comma is the only non-standard + // decimal separator we may encounter... + $stringValue = str_replace(',', '.', $stringValue); + + // ensure that number is really printed as float + return preg_match('/^-?[0-9]+$/', $stringValue) + ? $stringValue . '.0' + : $stringValue; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php new file mode 100644 index 0000000..ad77a0b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/IntegerNode.php @@ -0,0 +1,71 @@ +value === -PHP_INT_MAX - 1) { + // PHP_INT_MIN cannot be represented as a literal, because the sign is not part of the literal + return '(-' . PHP_INT_MAX . '-1)'; + + } elseif ($this->kind === self::KindDecimal) { + return (string) $this->value; + } + + if ($this->value < 0) { + $sign = '-'; + $str = (string) -$this->value; + } else { + $sign = ''; + $str = (string) $this->value; + } + + return match ($this->kind) { + self::KindBinary => $sign . '0b' . base_convert($str, 10, 2), + self::KindOctal => $sign . '0' . base_convert($str, 10, 8), + self::KindHexa => $sign . '0x' . base_convert($str, 10, 16), + default => throw new \Exception('Invalid number kind'), + }; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php new file mode 100644 index 0000000..39d3ec9 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/InterpolatedStringNode.php @@ -0,0 +1,77 @@ + */ + public array $parts, + public ?Position $position = null, + ) { + } + + + /** @param array $parts */ + public static function parse(array $parts, Position $position): static + { + foreach ($parts as $part) { + if ($part instanceof InterpolatedStringPartNode) { + $part->value = PhpHelpers::decodeEscapeSequences($part->value, '"'); + } + } + + return new static($parts, $position); + } + + + public function print(PrintContext $context): string + { + $s = ''; + $expr = false; + foreach ($this->parts as $part) { + if ($part instanceof InterpolatedStringPartNode) { + $s .= substr($context->encodeString($part->value, '"'), 1, -1); + continue; + } + + $partStr = $part->print($context); + if ($partStr[0] === '$' && $part->isVariable()) { + $s .= '{' . $partStr . '}'; + } else { + $s .= '" . (' . $partStr . ') . "'; + $expr = true; + } + } + + return $expr + ? '("' . $s . '")' + : '"' . $s . '"'; + } + + + public function &getIterator(): \Generator + { + foreach ($this->parts as &$item) { + yield $item; + } + Helpers::removeNulls($this->parts); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php new file mode 100644 index 0000000..9ff78cf --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/Scalar/NullNode.php @@ -0,0 +1,29 @@ + '\\', "\\'" => "'"]) + : PhpHelpers::decodeEscapeSequences(substr($str, 1, -1), '"'); + return new static($str, $position); + } + + + public function print(PrintContext $context): string + { + return $context->encodeString($this->value); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php new file mode 100644 index 0000000..764cbbb --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/ScalarNode.php @@ -0,0 +1,19 @@ + */ + public array $types, + public ?Position $position = null, + ) { + (function (IdentifierNode|NameNode ...$args) {})(...$types); + } + + + public function print(PrintContext $context): string + { + return $context->implode($this->types, '|'); + } + + + public function &getIterator(): \Generator + { + foreach ($this->types as &$item) { + yield $item; + } + Helpers::removeNulls($this->types); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php new file mode 100644 index 0000000..9f59981 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VarLikeIdentifierNode.php @@ -0,0 +1,21 @@ +name; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php new file mode 100644 index 0000000..4eccbae --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/Php/VariadicPlaceholderNode.php @@ -0,0 +1,35 @@ +outputMode = $tag::OutputKeepIndentation; + $tag->expectArguments(); + $node = new static; + $node->expression = $tag->parser->parseExpression(); + $node->modifier = $tag->parser->parseModifier(); + $node->modifier->escape = !$node->modifier->removeFilter('noescape'); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + "echo %modify(%node) %line;\n", + $this->modifier, + $this->expression, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->expression; + yield $this->modifier; + } +} + + +class_alias(PrintNode::class, Latte\Essential\Nodes\PrintNode::class); diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php new file mode 100644 index 0000000..ce877b0 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/StatementNode.php @@ -0,0 +1,15 @@ +head; + yield $this->main; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php b/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php new file mode 100644 index 0000000..a8c9f1b --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Nodes/TextNode.php @@ -0,0 +1,44 @@ +content === '' + ? '' + : 'echo ' . var_export($this->content, true) . ";\n"; + } + + + public function isWhitespace(): bool + { + return trim($this->content) === ''; + } + + + public function &getIterator(): \Generator + { + false && yield; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php b/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php new file mode 100644 index 0000000..d58241a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/PhpHelpers.php @@ -0,0 +1,263 @@ + $token) { + $next = $tokens[$n + 1] ?? [null, '']; + + if (is_array($token)) { + [$name, $token] = $token; + if ($name === T_ELSE || $name === T_ELSEIF) { + if ($next === ':' && $lastChar === '}') { + $res .= ';'; // semicolon needed in if(): ... if() ... else: + } + + $lastChar = ''; + $res .= $token; + + } elseif ($name === T_DOC_COMMENT || $name === T_COMMENT) { + $res .= preg_replace("#\n[ \t]*+(?!\n)#", "\n" . str_repeat("\t", $level), $token); + + } elseif ($name === T_WHITESPACE) { + $prev = $tokens[$n - 1]; + $lines = substr_count($token, "\n"); + if ($prev === '}' && in_array($next[0], [T_ELSE, T_ELSEIF, T_CATCH, T_FINALLY], true)) { + $token = ' '; + } elseif ($prev === '{' || $prev === '}' || $prev === ';' || $lines) { + $token = str_repeat("\n", max(1, $lines)) . str_repeat("\t", $level); // indent last line + } elseif ($prev[0] === T_OPEN_TAG) { + $token = ''; + } + + $res .= $token; + + } elseif ($name === T_OBJECT_OPERATOR) { + $lastChar = '->'; + $res .= $token; + + } elseif ($name === T_OPEN_TAG) { + $res .= " $v) { + $s .= $multiline + ? ($s === '' ? "\n" : '') . "\t" . ($indexed ? '' : self::dump($k) . ' => ') . self::dump($v) . ",\n" + : ($s === '' ? '' : ', ') . ($indexed ? '' : self::dump($k) . ' => ') . self::dump($v); + } + + return '[' . $s . ']'; + } elseif ($value === null) { + return 'null'; + } else { + return var_export($value, true); + } + } + + + public static function optimizeEcho(string $source): string + { + $res = ''; + $tokens = token_get_all($source); + $start = null; + + for ($i = 0; $i < count($tokens); $i++) { + $token = $tokens[$i]; + if ($token[0] === T_ECHO) { + if (!$start) { + $str = ''; + $start = strlen($res); + } + + } elseif ($start && $token[0] === T_CONSTANT_ENCAPSED_STRING && $token[1][0] === "'") { + $str .= stripslashes(substr($token[1], 1, -1)); + + } elseif ($start && $token === ';') { + if ($str !== '') { + $res = substr_replace( + $res, + 'echo ' . ($str === "\n" ? '"\n"' : var_export($str, true)), + $start, + strlen($res) - $start, + ); + } + + } elseif ($token[0] !== T_WHITESPACE) { + $start = null; + } + + $res .= is_array($token) ? $token[1] : $token; + } + + return $res; + } + + + public static function decodeNumber(string $str, &$base = null): int|float|null + { + $str = str_replace('_', '', $str); + + if ($str[0] !== '0' || $str === '0') { + $base = 10; + return $str + 0; + } elseif ($str[1] === 'x' || $str[1] === 'X') { + $base = 16; + return hexdec($str); + } elseif ($str[1] === 'b' || $str[1] === 'B') { + $base = 2; + return bindec($str); + } elseif (strpbrk($str, '89')) { + return null; + } else { + $base = 8; + return octdec($str); + } + } + + + public static function decodeEscapeSequences(string $str, ?string $quote): string + { + if ($quote !== null) { + $str = str_replace('\\' . $quote, $quote, $str); + } + + return preg_replace_callback( + '~\\\([\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}|u\{([0-9a-fA-F]+)\})~', + function ($matches) { + $ch = $matches[1]; + $replacements = [ + '\\' => '\\', + '$' => '$', + 'n' => "\n", + 'r' => "\r", + 't' => "\t", + 'f' => "\f", + 'v' => "\v", + 'e' => "\x1B", + ]; + if (isset($replacements[$ch])) { + return $replacements[$ch]; + } elseif ($ch[0] === 'x' || $ch[0] === 'X') { + return chr(hexdec(substr($ch, 1))); + } elseif ($ch[0] === 'u') { + return self::codePointToUtf8(hexdec($matches[2])); + } else { + $num = octdec($ch); + if ($num > 255) { + throw new CompileException("Octal escape sequence \\$ch is greater than \\377"); + } + return chr($num); + } + }, + $str, + ); + } + + + private static function codePointToUtf8(int $num): string + { + return match (true) { + $num <= 0x7F => chr($num), + $num <= 0x7FF => chr(($num >> 6) + 0xC0) . chr(($num & 0x3F) + 0x80), + $num <= 0xFFFF => chr(($num >> 12) + 0xE0) . chr((($num >> 6) & 0x3F) + 0x80) . chr(($num & 0x3F) + 0x80), + $num <= 0x1FFFFF => chr(($num >> 18) + 0xF0) . chr((($num >> 12) & 0x3F) + 0x80) + . chr((($num >> 6) & 0x3F) + 0x80) . chr(($num & 0x3F) + 0x80), + default => throw new CompileException('Invalid UTF-8 codepoint escape sequence: Codepoint too large'), + }; + } + + + public static function checkCode(string $phpBinary, string $code, string $name): void + { + $process = proc_open( + $phpBinary . ' -l -n', + [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], + $pipes, + null, + null, + ['bypass_shell' => true], + ); + if (!is_resource($process)) { + throw new CompileException('Unable to check that the generated PHP is correct.'); + } + + fwrite($pipes[0], $code); + fclose($pipes[0]); + $error = stream_get_contents($pipes[1]); + if (!proc_close($process)) { + return; + } + $error = strip_tags(explode("\n", $error)[1]); + $position = preg_match('~ on line (\d+)~', $error, $m) + ? new Position((int) $m[1], 0) + : null; + $error = preg_replace('~(^Fatal error: | in Standard input code| on line \d+)~', '', $error); + throw (new CompileException('Error in generated code: ' . trim($error), $position)) + ->setSource($code, $name); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Position.php b/vendor/latte/latte/src/Latte/Compiler/Position.php new file mode 100644 index 0000000..8c5d344 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Position.php @@ -0,0 +1,47 @@ +line + $lines, + strlen($str) - strrpos($str, "\n"), + $this->offset + strlen($str), + ); + } else { + return new self( + $this->line, + $this->column + strlen($str), + $this->offset + strlen($str), + ); + } + } + + + public function __toString(): string + { + return "on line $this->line" . ($this->column ? " at column $this->column" : ''); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/PrintContext.php b/vendor/latte/latte/src/Latte/Compiler/PrintContext.php new file mode 100644 index 0000000..d7a3f35 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/PrintContext.php @@ -0,0 +1,288 @@ +escaperStack[] = new Escaper($contentType); + } + + + /** + * Expands %node, %dump, %raw, %args, %line, %escape(), %modify(), %modifyContent() in code. + */ + public function format(string $mask, mixed ...$args): string + { + $pos = 0; // enumerate arguments except for %escape + $mask = preg_replace_callback( + '#%([a-z]{3,})#i', + function ($m) use (&$pos) { + return $m[1] === 'escape' + ? '%0.escape' + : '%' . ($pos++) . '.' . $m[1]; + }, + $mask, + ); + + $mask = preg_replace_callback( + '#% (\d+) \. (escape|modify(?:Content)?) ( \( ([^()]*+|(?-2))+ \) )#xi', + function ($m) use ($args) { + [, $pos, $fn, $var] = $m; + $var = substr($var, 1, -1); + /** @var Nodes\ModifierNode[] $args */ + return match ($fn) { + 'modify' => $args[$pos]->printSimple($this, $var), + 'modifyContent' => $args[$pos]->printContentAware($this, $var), + 'escape' => end($this->escaperStack)->escape($var), + }; + }, + $mask, + ); + + return preg_replace_callback( + '#([,+]?\s*)? % (\d+) \. ([a-z]{3,}) (\?)? (\s*\+\s*)? ()#xi', + function ($m) use ($args) { + [, $left, $pos, $format, $cond, $right] = $m; + $arg = $args[$pos]; + + $code = match ($format) { + 'dump' => PhpHelpers::dump($arg), + 'node' => match (true) { + !$arg => '', + $arg instanceof OperatorNode && $arg->getOperatorPrecedence() < Expression\AssignNode::Precedence => '(' . $arg->print($this) . ')', + default => $arg->print($this), + }, + 'raw' => (string) $arg, + 'args' => $this->implode($arg instanceof Expression\ArrayNode ? $arg->toArguments() : $arg), + 'line' => $arg?->line ? "/* pos $arg->line" . ($arg->column ? ":$arg->column" : '') . ' */' : '', + }; + + if ($cond && ($code === '[]' || $code === '' || $code === 'null')) { + return $right ? $left : $right; + } + + return $code === '' + ? trim($left) . $right + : $left . $code . $right; + }, + $mask, + ); + } + + + public function beginEscape(): Escaper + { + return $this->escaperStack[] = $this->getEscaper(); + } + + + public function restoreEscape(): void + { + array_pop($this->escaperStack); + } + + + public function getEscaper(): Escaper + { + return clone end($this->escaperStack); + } + + + public function addBlock(Block $block): void + { + $block->escaping = $this->getEscaper()->export(); + $block->method = 'block' . ucfirst(trim(preg_replace('#\W+#', '_', $block->name->print($this)), '_')); + $lower = strtolower($block->method); + $used = $this->blocks + ['block' => 1]; + $counter = null; + while (isset($used[$lower . $counter])) { + $counter++; + } + + $block->method .= $counter; + $this->blocks[$lower . $counter] = $block; + } + + + public function generateId(): int + { + return $this->counter++; + } + + + // PHP helpers + + + public function encodeString(string $str, string $quote = "'"): string + { + return $quote === "'" + ? "'" . addcslashes($str, "'\\") . "'" + : '"' . addcslashes($str, "\n\r\t\f\v$\"\\") . '"'; + } + + + #[\Deprecated] + public function infixOp(Node $node, Node $leftNode, string $operatorString, Node $rightNode): string + { + return $this->parenthesize($node, $leftNode, OperatorNode::AssocLeft) + . $operatorString + . $this->parenthesize($node, $rightNode, OperatorNode::AssocRight); + } + + + #[\Deprecated] + public function prefixOp(Node $node, string $operatorString, Node $expr): string + { + return $operatorString . $this->parenthesize($node, $expr, OperatorNode::AssocRight); + } + + + #[\Deprecated] + public function postfixOp(Node $node, Node $var, string $operatorString): string + { + return $this->parenthesize($node, $var, OperatorNode::AssocLeft) . $operatorString; + } + + + /** + * Prints an expression node with the least amount of parentheses necessary to preserve the meaning. + */ + public function parenthesize(OperatorNode $parentNode, Node $childNode, int $childPosition): string + { + [$parentPrec, $parentAssoc] = $parentNode->getOperatorPrecedence(); + [$childPrec] = $childNode instanceof OperatorNode ? $childNode->getOperatorPrecedence() : null; + return $childPrec && ($childPrec < $parentPrec || ($parentPrec === $childPrec && $parentAssoc !== $childPosition)) + ? '(' . $childNode->print($this) . ')' + : $childNode->print($this); + } + + + /** + * Prints an array of nodes and implodes the printed values with $glue + */ + public function implode(array $nodes, string $glue = ', '): string + { + $pNodes = []; + foreach ($nodes as $node) { + if ($node === null) { + $pNodes[] = ''; + } else { + $pNodes[] = $node->print($this); + } + } + + return implode($glue, $pNodes); + } + + + public function objectProperty(Node $node): string + { + return $node instanceof Nodes\NameNode || $node instanceof Nodes\IdentifierNode + ? (string) $node + : '{' . $node->print($this) . '}'; + } + + + public function memberAsString(Node $node): string + { + return $node instanceof Nodes\NameNode || $node instanceof Nodes\IdentifierNode + ? $this->encodeString((string) $node) + : $node->print($this); + } + + + /** + * Wraps the LHS of a call in parentheses if needed. + */ + public function callExpr(Node $expr): string + { + return $expr instanceof Nodes\NameNode + || $expr instanceof Expression\VariableNode + || $expr instanceof Expression\ArrayAccessNode + || $expr instanceof Expression\FunctionCallNode + || $expr instanceof Expression\MethodCallNode + || $expr instanceof Expression\StaticMethodCallNode + || $expr instanceof Expression\ArrayNode + ? $expr->print($this) + : '(' . $expr->print($this) . ')'; + } + + + /** + * Wraps the LHS of a dereferencing operation in parentheses if needed. + */ + public function dereferenceExpr(Node $expr): string + { + return $expr instanceof Expression\VariableNode + || $expr instanceof Nodes\NameNode + || $expr instanceof Expression\ArrayAccessNode + || $expr instanceof Expression\PropertyFetchNode + || $expr instanceof Expression\StaticPropertyFetchNode + || $expr instanceof Expression\FunctionCallNode + || $expr instanceof Expression\MethodCallNode + || $expr instanceof Expression\StaticMethodCallNode + || $expr instanceof Expression\ArrayNode + || $expr instanceof Scalar\StringNode + || $expr instanceof Scalar\BooleanNode + || $expr instanceof Scalar\NullNode + || $expr instanceof Expression\ConstantFetchNode + || $expr instanceof Expression\ClassConstantFetchNode + ? $expr->print($this) + : '(' . $expr->print($this) . ')'; + } + + + /** + * @param Nodes\ArgumentNode[] $args + */ + public function argumentsAsArray(array $args): string + { + $items = array_map(fn(Nodes\ArgumentNode $arg) => $arg->toArrayItem(), $args); + return '[' . $this->implode($items) . ']'; + } + + + /** + * Ensures that expression evaluates to string or throws exception. + */ + public function ensureString(Nodes\ExpressionNode $name, string $entity): string + { + return $name instanceof Scalar\StringNode + ? $name->print($this) + : $this->format( + '(LR\Helpers::stringOrNull($ʟ_tmp = %node) ?? throw new InvalidArgumentException(sprintf(%dump, get_debug_type($ʟ_tmp))))', + $name, + $entity . ' must be a string, %s given.', + ); + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/Tag.php b/vendor/latte/latte/src/Latte/Compiler/Tag.php new file mode 100644 index 0000000..61bf3b8 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/Tag.php @@ -0,0 +1,117 @@ +parser = new TagParser($tokens); + } + + + public function isInHead(): bool + { + return $this->inHead && !$this->parent; + } + + + public function isInText(): bool + { + return !$this->inTag; + } + + + public function isNAttribute(): bool + { + return $this->prefix !== null; + } + + + public function getNotation(bool $withArgs = false): string + { + return $this->isNAttribute() + ? TemplateLexer::NPrefix . ($this->prefix ? $this->prefix . '-' : '') + . $this->name + . ($withArgs ? '="' . $this->parser->text . '"' : '') + : '{' + . ($this->closing ? '/' : '') + . $this->name + . ($withArgs ? $this->parser->text : '') + . '}'; + } + + + /** + * @param class-string[] $classes + */ + public function closestTag(array $classes, ?callable $condition = null): ?self + { + $tag = $this->parent; + while ($tag && ( + !in_array($tag->node ? $tag->node::class : null, $classes, true) + || ($condition && !$condition($tag)) + )) { + $tag = $tag->parent; + } + + return $tag; + } + + + public function expectArguments(string $what = 'arguments'): void + { + if ($this->parser->isEnd()) { + throw new CompileException("Missing $what in " . $this->getNotation(), $this->position); + } + } + + + public function replaceNAttribute(AreaNode $node): void + { + $index = array_search($this->nAttribute, $this->htmlElement->attributes->children, true); + $this->htmlElement->attributes->children[$index] = $this->nAttribute = $node; + } +} diff --git a/vendor/latte/latte/src/Latte/Compiler/TagLexer.php b/vendor/latte/latte/src/Latte/Compiler/TagLexer.php new file mode 100644 index 0000000..dd50b7a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Compiler/TagLexer.php @@ -0,0 +1,401 @@ + Token::Php_LogicalAnd, + 'array' => Token::Php_Array, + 'clone' => Token::Php_Clone, + 'default' => Token::Php_Default, + 'in' => Token::Php_In, + 'instanceof' => Token::Php_Instanceof, + 'new' => Token::Php_New, + 'or' => Token::Php_LogicalOr, + 'return' => Token::Php_Return, + 'xor' => Token::Php_LogicalXor, + 'null' => Token::Php_Null, + 'true' => Token::Php_True, + 'false' => Token::Php_False, + ]; + + private const KeywordsFollowed = [ // must follows ( & = + 'empty' => Token::Php_Empty, + 'fn' => Token::Php_Fn, + 'function' => Token::Php_Function, + 'isset' => Token::Php_Isset, + 'list' => Token::Php_List, + 'match' => Token::Php_Match, + 'use' => Token::Php_Use, + ]; + + /** @var Token[] */ + private array $tokens; + private string $input; + private int $offset; + private Position $position; + + + /** @return Token[] */ + public function tokenize(string $input, ?Position $position = null): array + { + $position ??= new Position; + $this->tokens = $this->tokenizePartially($input, $position, 0); + if ($this->offset !== strlen($input)) { + $token = str_replace("\n", '\n', substr($input, $this->offset, 10)); + throw new CompileException("Unexpected '$token'", $position); + } + + $this->tokens[] = new Token(Token::End, '', $position); + return $this->tokens; + } + + + /** @return Token[] */ + public function tokenizePartially(string $input, Position &$position, ?int $ofs = null): array + { + $this->input = $input; + $this->offset = $ofs ?? $position->offset; + $this->position = &$position; + $this->tokens = []; + $this->tokenizeCode(); + return $this->tokens; + } + + + /** @return Token[]|null */ + public function tokenizeUnquotedString(string $input, Position $position, bool $colon, int $offsetDelta): ?array + { + preg_match( + $colon + ? '~ ( [./@_a-z0-9#!-] | :(?!:) | \{\$ [_a-z0-9\[\]()>-]+ } )++ (?=\s+[!"\'$(\[{,\\\|\~\w-] | [,|] | \s*$) ~xAi' + : '~ ( [./@_a-z0-9#!-] | \{\$ [_a-z0-9\[\]()>-]+ } )++ (?=\s+[!"\'$(\[{,\\\|\~\w-] | [,:|] | \s*$) ~xAi', + $input, + $match, + offset: $position->offset - $offsetDelta, + ); + $position = new Position($position->line, $position->column - 1, $position->offset - 1); + return $match && !is_numeric($match[0]) + ? $this->tokenize('"' . $match[0] . '"', $position) + : null; + } + + + private function tokenizeCode(): void + { + $re = <<<'XX' + ~(?J)(?n) # allow duplicate named groups, no auto capture + (?(DEFINE) (?
' . htmlspecialchars($file) . ''; + } + + + /** + * @param mixed[] $vars + */ + public function printVars(array $vars): void + { + $res = ''; + foreach ($vars as $name => $value) { + if (!str_starts_with($name, 'ʟ_')) { + $type = $this->getType($value); + $res .= "{varType $type $$name}\n"; + } + } + + $this->printHeader('varPrint'); + $this->printCode($res ?: 'No variables', 'latte'); + } + + + /** + * @param mixed[] $props + */ + public function addProperties(Php\ClassType $class, array $props): void + { + foreach ($props as $name => $value) { + $class->removeProperty($name); + $type = $this->getType($value); + $prop = $class->addProperty($name); + $prop->setType($type); + } + } + + + /** + * @param callable[] $funcs + */ + public function addFunctions(Php\ClassType $class, array $funcs): void + { + foreach ($funcs as $name => $func) { + $method = (new Php\Factory)->fromCallable($func); + $type = $this->printType($method->getReturnType(), $method->isReturnNullable(), $class->getNamespace()) ?: 'mixed'; + $class->addComment("@method $type $name" . $this->printParameters($method, $class->getNamespace())); + } + } + + + private function printType(?string $type, bool $nullable, ?Php\PhpNamespace $namespace): string + { + if ($type === null) { + return ''; + } + + if ($namespace) { + $type = $namespace->simplifyName($type); + } + + if ($nullable && strcasecmp($type, 'mixed')) { + $type = str_contains($type, '|') + ? $type . '|null' + : '?' . $type; + } + + return $type; + } + + + public function printParameters( + Php\Closure|Php\GlobalFunction|Php\Method $function, + ?Php\PhpNamespace $namespace = null, + ): string + { + $params = []; + $list = $function->getParameters(); + foreach ($list as $param) { + $variadic = $function->isVariadic() && $param === end($list); + $params[] = ltrim($this->printType($param->getType(), $param->isNullable(), $namespace) . ' ') + . ($param->isReference() ? '&' : '') + . ($variadic ? '...' : '') + . '$' . $param->getName() + . ($param->hasDefaultValue() && !$variadic ? ' = ' . var_export($param->getDefaultValue(), true) : ''); + } + + return '(' . implode(', ', $params) . ')'; + } + + + public function printBegin(): void + { + echo ''; + echo ''; + echo "
\n"; + } + + + public function printEnd(): void + { + echo "
\n"; + } + + + public function printHeader(string $string): void + { + echo "

", + htmlspecialchars($string), + "

\n"; + } + + + public function printCode(string $code, string $lang = 'php'): void + { + echo '
',
+			htmlspecialchars($code),
+			"
\n"; + } + + + private function getType($value): string + { + return $value === null ? 'mixed' : get_debug_type($value); + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/CachingIterator.php b/vendor/latte/latte/src/Latte/Essential/CachingIterator.php new file mode 100644 index 0000000..98d2444 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/CachingIterator.php @@ -0,0 +1,229 @@ +getIterator(); + } while (!$iterator instanceof \Iterator); + } elseif ($iterator instanceof \Traversable) { + if (!$iterator instanceof \Iterator) { + $iterator = new \IteratorIterator($iterator); + } + } else { + throw new \InvalidArgumentException(sprintf('Invalid argument passed to foreach; array or Traversable expected, %s given.', get_debug_type($iterator))); + } + + parent::__construct($iterator, 0); + $this->parent = $parent; + } + + + /** + * Is the current element the first one? + */ + public function isFirst(?int $width = null): bool + { + return $this->counter === 1 || ($width && $this->counter !== 0 && (($this->counter - 1) % $width) === 0); + } + + + /** + * Is the current element the last one? + */ + public function isLast(?int $width = null): bool + { + return !$this->hasNext() || ($width && ($this->counter % $width) === 0); + } + + + /** + * Is the iterator empty? + */ + public function isEmpty(): bool + { + return $this->counter === 0; + } + + + /** + * Is the counter odd? + */ + public function isOdd(): bool + { + return $this->counter % 2 === 1; + } + + + /** + * Is the counter even? + */ + public function isEven(): bool + { + return $this->counter % 2 === 0; + } + + + /** + * Returns the 1-indexed counter. + */ + public function getCounter(): int + { + return $this->counter; + } + + + /** + * Returns the 0-indexed counter. + */ + public function getCounter0(): int + { + return max(0, $this->counter - 1); + } + + + /** + * Decrements counter. + */ + public function skipRound(): void + { + $this->counter = max($this->counter - 1, 0); + } + + + /** + * Returns the counter as string + */ + public function __toString(): string + { + return (string) $this->counter; + } + + + /** + * Returns the count of elements. + */ + public function count(): int + { + $inner = $this->getInnerIterator(); + if ($inner instanceof \Countable) { + return $inner->count(); + + } else { + throw new \LogicException('Iterator is not countable.'); + } + } + + + /** + * Forwards to the next element. + */ + public function next(): void + { + parent::next(); + if (parent::valid()) { + $this->counter++; + } + } + + + /** + * Rewinds the Iterator. + */ + public function rewind(): void + { + parent::rewind(); + $this->counter = parent::valid() ? 1 : 0; + } + + + /** + * Returns the next key or null if position is not valid. + */ + public function getNextKey(): mixed + { + $iterator = $this->getInnerIterator(); + return $iterator->valid() ? $iterator->key() : null; + } + + + /** + * Returns the next element or null if position is not valid. + */ + public function getNextValue(): mixed + { + $iterator = $this->getInnerIterator(); + return $iterator->valid() ? $iterator->current() : null; + } + + + /** + * Returns the iterator surrounding the current one. + */ + public function getParent(): ?self + { + return $this->parent; + } + + + /********************* property accessor ****************d*g**/ + + + /** + * Returns property value. + * @throws \LogicException if the property is not defined. + */ + public function __get(string $name): mixed + { + if (method_exists($this, $m = 'get' . $name) || method_exists($this, $m = 'is' . $name)) { + return $this->$m(); + } + + throw new \LogicException('Attempt to read undeclared property ' . static::class . "::\$$name."); + } + + + /** + * Is property defined? + */ + public function __isset(string $name): bool + { + return method_exists($this, 'get' . $name) || method_exists($this, 'is' . $name); + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/CoreExtension.php b/vendor/latte/latte/src/Latte/Essential/CoreExtension.php new file mode 100644 index 0000000..532610a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/CoreExtension.php @@ -0,0 +1,287 @@ +filters = new Filters; + } + + + public function beforeCompile(Latte\Engine $engine): void + { + $this->engine = $engine; + } + + + public function beforeRender(Runtime\Template $template): void + { + $this->engine = $template->getEngine(); + $this->filters->locale = $this->engine->getLocale(); + } + + + public function getTags(): array + { + return [ + 'embed' => Nodes\EmbedNode::create(...), + 'define' => Nodes\DefineNode::create(...), + 'block' => Nodes\BlockNode::create(...), + 'layout' => Nodes\ExtendsNode::create(...), + 'extends' => Nodes\ExtendsNode::create(...), + 'import' => Nodes\ImportNode::create(...), + 'include' => $this->includeSplitter(...), + + 'n:attr' => Nodes\NAttrNode::create(...), + 'n:class' => Nodes\NClassNode::create(...), + 'n:tag' => Nodes\NTagNode::create(...), + + 'parameters' => Nodes\ParametersNode::create(...), + 'varType' => Nodes\VarTypeNode::create(...), + 'varPrint' => Nodes\VarPrintNode::create(...), + 'templateType' => Nodes\TemplateTypeNode::create(...), + 'templatePrint' => Nodes\TemplatePrintNode::create(...), + + '=' => Latte\Compiler\Nodes\PrintNode::create(...), + 'do' => Nodes\DoNode::create(...), + 'php' => Nodes\DoNode::create(...), // obsolete + 'contentType' => Nodes\ContentTypeNode::create(...), + 'spaceless' => Nodes\SpacelessNode::create(...), + 'capture' => Nodes\CaptureNode::create(...), + 'l' => fn(Tag $tag) => new TextNode('{', $tag->position), + 'r' => fn(Tag $tag) => new TextNode('}', $tag->position), + 'syntax' => $this->parseSyntax(...), + + 'dump' => Nodes\DumpNode::create(...), + 'debugbreak' => Nodes\DebugbreakNode::create(...), + 'trace' => Nodes\TraceNode::create(...), + + 'var' => Nodes\VarNode::create(...), + 'default' => Nodes\VarNode::create(...), + + 'try' => Nodes\TryNode::create(...), + 'rollback' => Nodes\RollbackNode::create(...), + + 'foreach' => Nodes\ForeachNode::create(...), + 'for' => Nodes\ForNode::create(...), + 'while' => Nodes\WhileNode::create(...), + 'iterateWhile' => Nodes\IterateWhileNode::create(...), + 'sep' => Nodes\FirstLastSepNode::create(...), + 'last' => Nodes\FirstLastSepNode::create(...), + 'first' => Nodes\FirstLastSepNode::create(...), + 'skipIf' => Nodes\JumpNode::create(...), + 'breakIf' => Nodes\JumpNode::create(...), + 'exitIf' => Nodes\JumpNode::create(...), + 'continueIf' => Nodes\JumpNode::create(...), + + 'if' => Nodes\IfNode::create(...), + 'ifset' => Nodes\IfNode::create(...), + 'ifchanged' => Nodes\IfChangedNode::create(...), + 'n:ifcontent' => Nodes\IfContentNode::create(...), + 'n:else' => Nodes\NElseNode::create(...), + 'n:elseif' => Nodes\NElseNode::create(...), + 'switch' => Nodes\SwitchNode::create(...), + ]; + } + + + public function getFilters(): array + { + return [ + 'batch' => $this->filters->batch(...), + 'breakLines' => $this->filters->breaklines(...), + 'breaklines' => $this->filters->breaklines(...), + 'bytes' => $this->filters->bytes(...), + 'capitalize' => extension_loaded('mbstring') + ? $this->filters->capitalize(...) + : fn() => throw new RuntimeException('Filter |capitalize requires mbstring extension.'), + 'ceil' => $this->filters->ceil(...), + 'checkUrl' => $this->filters->checkUrl(...), + 'clamp' => $this->filters->clamp(...), + 'dataStream' => $this->filters->dataStream(...), + 'datastream' => $this->filters->dataStream(...), + 'date' => $this->filters->date(...), + 'escape' => Latte\Runtime\Helpers::nop(...), + 'escapeCss' => Latte\Runtime\Helpers::escapeCss(...), + 'escapeHtml' => Latte\Runtime\HtmlHelpers::escapeText(...), + 'escapeHtmlComment' => Latte\Runtime\HtmlHelpers::escapeComment(...), + 'escapeICal' => Latte\Runtime\Helpers::escapeICal(...), + 'escapeJs' => Latte\Runtime\Helpers::escapeJs(...), + 'escapeUrl' => 'rawurlencode', + 'escapeXml' => Latte\Runtime\XmlHelpers::escapeText(...), + 'explode' => $this->filters->explode(...), + 'filter' => $this->filters->filter(...), + 'first' => $this->filters->first(...), + 'firstLower' => extension_loaded('mbstring') + ? $this->filters->firstLower(...) + : fn() => throw new RuntimeException('Filter |firstLower requires mbstring extension.'), + 'firstUpper' => extension_loaded('mbstring') + ? $this->filters->firstUpper(...) + : fn() => throw new RuntimeException('Filter |firstUpper requires mbstring extension.'), + 'floor' => $this->filters->floor(...), + 'group' => $this->filters->group(...), + 'implode' => $this->filters->implode(...), + 'indent' => $this->filters->indent(...), + 'join' => $this->filters->implode(...), + 'last' => $this->filters->last(...), + 'length' => $this->filters->length(...), + 'localDate' => $this->filters->localDate(...), + 'lower' => extension_loaded('mbstring') + ? $this->filters->lower(...) + : fn() => throw new RuntimeException('Filter |lower requires mbstring extension.'), + 'number' => $this->filters->number(...), + 'padLeft' => $this->filters->padLeft(...), + 'padRight' => $this->filters->padRight(...), + 'query' => $this->filters->query(...), + 'random' => $this->filters->random(...), + 'repeat' => $this->filters->repeat(...), + 'replace' => $this->filters->replace(...), + 'replaceRe' => $this->filters->replaceRe(...), + 'replaceRE' => $this->filters->replaceRe(...), + 'reverse' => $this->filters->reverse(...), + 'round' => $this->filters->round(...), + 'slice' => $this->filters->slice(...), + 'sort' => $this->filters->sort(...), + 'spaceless' => $this->filters->strip(...), + 'split' => $this->filters->explode(...), + 'strip' => $this->filters->strip(...), // obsolete + 'stripHtml' => $this->filters->stripHtml(...), + 'striphtml' => $this->filters->stripHtml(...), + 'stripTags' => $this->filters->stripTags(...), + 'striptags' => $this->filters->stripTags(...), + 'substr' => $this->filters->substring(...), + 'trim' => $this->filters->trim(...), + 'truncate' => $this->filters->truncate(...), + 'upper' => extension_loaded('mbstring') + ? $this->filters->upper(...) + : fn() => throw new RuntimeException('Filter |upper requires mbstring extension.'), + 'webalize' => class_exists(Nette\Utils\Strings::class) + ? Nette\Utils\Strings::webalize(...) + : fn() => throw new RuntimeException('Filter |webalize requires nette/utils package.'), + ]; + } + + + public function getFunctions(): array + { + return [ + 'clamp' => $this->filters->clamp(...), + 'divisibleBy' => $this->filters->divisibleBy(...), + 'even' => $this->filters->even(...), + 'first' => $this->filters->first(...), + 'group' => $this->filters->group(...), + 'last' => $this->filters->last(...), + 'odd' => $this->filters->odd(...), + 'slice' => $this->filters->slice(...), + 'hasBlock' => fn(Runtime\Template $template, string $name): bool => $template->hasBlock($name), + 'hasTemplate' => fn(Runtime\Template $template, string $name): bool => $this->hasTemplate($name, $template->getName()), + ]; + } + + + public function getPasses(): array + { + $passes = new Passes($this->engine); + return [ + 'internalVariables' => $passes->forbiddenVariablesPass(...), + 'checkUrls' => $passes->checkUrlsPass(...), + 'overwrittenVariables' => Nodes\ForeachNode::overwrittenVariablesPass(...), + 'customFunctions' => $passes->customFunctionsPass(...), + 'moveTemplatePrintToHead' => Nodes\TemplatePrintNode::moveToHeadPass(...), + 'nElse' => Nodes\NElseNode::processPass(...), + 'scriptTagQuotes' => $passes->scriptTagQuotesPass(...), + ]; + } + + + public function getCacheKey(Latte\Engine $engine): mixed + { + return array_keys($engine->getFunctions()); + } + + + /** + * {include [file] "file" [with blocks] [,] [params]} + * {include [block] name [,] [params]} + */ + private function includeSplitter(Tag $tag, TemplateParser $parser): Nodes\IncludeBlockNode|Nodes\IncludeFileNode + { + $tag->expectArguments(); + $mod = $tag->parser->tryConsumeTokenBeforeUnquotedString('block', 'file'); + if ($mod) { + $block = $mod->text === 'block'; + } elseif ($tag->parser->stream->tryConsume('#')) { + $block = true; + } else { + $name = $tag->parser->parseUnquotedStringOrExpression(); + $block = $name instanceof Scalar\StringNode && preg_match('~[\w-]+$~DA', $name->value); + } + $tag->parser->stream->seek(0); + + return $block + ? Nodes\IncludeBlockNode::create($tag, $parser) + : Nodes\IncludeFileNode::create($tag); + } + + + /** + * {syntax ...} + */ + private function parseSyntax(Tag $tag, TemplateParser $parser): \Generator + { + if ($tag->isNAttribute() && $tag->prefix !== $tag::PrefixNone) { + throw new Latte\CompileException("Use n:syntax instead of {$tag->getNotation()}", $tag->position); + } + $tag->expectArguments(); + $token = $tag->parser->stream->consume(); + $lexer = $parser->getLexer(); + $lexer->setSyntax($token->text, $tag->isNAttribute() ? null : $tag->name); + [$inner] = yield; + if (!$tag->isNAttribute()) { + $lexer->popSyntax(); + } + return $inner; + } + + + /** + * Checks if template exists. + */ + private function hasTemplate(string $name, string $referringName): bool + { + try { + $name = $this->engine->getLoader()->getReferredName($name, $referringName); + $this->engine->createTemplate($name, [], clearCache: false); + return true; + } catch (Latte\TemplateNotFoundException) { + return false; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Filters.php b/vendor/latte/latte/src/Latte/Essential/Filters.php new file mode 100644 index 0000000..1755de3 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Filters.php @@ -0,0 +1,775 @@ +validate([null, 'html', 'html/attr', 'xml', 'xml/attr'], __FUNCTION__); + $info->contentType = ContentType::Text; + return Latte\Runtime\HtmlHelpers::convertHtmlToText((string) $s); + } + + + /** + * Removes tags from HTML (but remains HTML entities). + */ + public static function stripTags(FilterInfo $info, $s): string + { + $info->contentType ??= ContentType::Html; + $info->validate(['html', 'html/attr', 'xml', 'xml/attr'], __FUNCTION__); + return strip_tags((string) $s); + } + + + /** + * Replaces all repeated white spaces with a single space. + */ + public static function strip(FilterInfo $info, string $s): string + { + return $info->contentType === ContentType::Html + ? trim(self::spacelessHtml($s)) + : trim(self::spacelessText($s)); + } + + + /** + * Replaces all repeated white spaces with a single space. + */ + public static function spacelessHtml(string $s, bool &$strip = true): string + { + return preg_replace_callback( + '#[ \t\r\n]+|<(/)?(textarea|pre|script)(?=\W)#si', + function ($m) use (&$strip) { + if (empty($m[2])) { + return $strip ? ' ' : $m[0]; + } else { + $strip = !empty($m[1]); + return $m[0]; + } + }, + $s, + ); + } + + + /** + * Output buffering handler for spacelessHtml. + */ + public static function spacelessHtmlHandler(string $s, ?int $phase = null): string + { + static $strip; + $left = $right = ''; + + if ($phase & PHP_OUTPUT_HANDLER_START) { + $strip = true; + $tmp = ltrim($s); + $left = substr($s, 0, strlen($s) - strlen($tmp)); + $s = $tmp; + } + + if ($phase & PHP_OUTPUT_HANDLER_FINAL) { + $tmp = rtrim($s); + $right = substr($s, strlen($tmp)); + $s = $tmp; + } + + return $left . self::spacelessHtml($s, $strip) . $right; + } + + + /** + * Replaces all repeated white spaces with a single space. + */ + public static function spacelessText(string $s): string + { + return preg_replace('#[ \t\r\n]+#', ' ', $s); + } + + + /** + * Indents plain text or HTML the content from the left. + */ + public static function indent(FilterInfo $info, string $s, int $level = 1, string $chars = "\t"): string + { + if ($level < 1) { + // do nothing + } elseif ($info->contentType === ContentType::Html) { + $s = preg_replace_callback('#<(textarea|pre).*? strtr($m[0], " \t\r\n", "\x1F\x1E\x1D\x1A"), $s); + if (preg_last_error()) { + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + $s = preg_replace('#(?:^|[\r\n]+)(?=[^\r\n])#', '$0' . str_repeat($chars, $level), $s); + $s = strtr($s, "\x1F\x1E\x1D\x1A", " \t\r\n"); + } else { + $s = preg_replace('#(?:^|[\r\n]+)(?=[^\r\n])#', '$0' . str_repeat($chars, $level), $s); + } + + return $s; + } + + + /** + * Join array of text or HTML elements with a string. + * @param string[] $arr + */ + public static function implode(array $arr, string $glue = ''): string + { + return implode($glue, $arr); + } + + + /** + * Splits a string by a string. + */ + public static function explode(string $value, string $separator = ''): array + { + return $separator === '' + ? preg_split('//u', $value, -1, PREG_SPLIT_NO_EMPTY) + : explode($separator, $value); + } + + + /** + * Repeats text. + */ + public static function repeat(FilterInfo $info, $s, int $count): string + { + return str_repeat((string) $s, $count); + } + + + /** + * Date/time formatting. + */ + public static function date( + string|int|\DateTimeInterface|\DateInterval|null $time, + string $format = "j.\u{a0}n.\u{a0}Y", + ): ?string + { + if ($time == null) { // intentionally == + return null; + } elseif ($time instanceof \DateInterval) { + return $time->format($format); + } elseif (is_numeric($time)) { + $time = (new \DateTime)->setTimestamp((int) $time); + } elseif (!$time instanceof \DateTimeInterface) { + $time = new \DateTime($time); + } + + return $time->format($format); + } + + + /** + * Date/time formatting according to locale. + */ + public function localDate( + string|int|\DateTimeInterface|null $value, + ?string $format = null, + ?string $date = null, + ?string $time = null, + ): ?string + { + if ($this->locale === null) { + throw new Latte\RuntimeException('Filter |localDate requires the locale to be set using Engine::setLocale()'); + } elseif ($value == null) { // intentionally == + return null; + } elseif (is_numeric($value)) { + $value = (new \DateTime)->setTimestamp((int) $value); + } elseif (!$value instanceof \DateTimeInterface) { + $value = new \DateTime($value); + $errors = \DateTime::getLastErrors(); + if (!empty($errors['warnings'])) { + throw new \InvalidArgumentException(reset($errors['warnings'])); + } + } + + if ($format === null) { + $xlt = ['' => \IntlDateFormatter::NONE, 'full' => \IntlDateFormatter::FULL, 'long' => \IntlDateFormatter::LONG, 'medium' => \IntlDateFormatter::MEDIUM, 'short' => \IntlDateFormatter::SHORT, + 'relative-full' => \IntlDateFormatter::RELATIVE_FULL, 'relative-long' => \IntlDateFormatter::RELATIVE_LONG, 'relative-medium' => \IntlDateFormatter::RELATIVE_MEDIUM, 'relative-short' => \IntlDateFormatter::RELATIVE_SHORT]; + $time ??= ''; + $date ??= $time === '' ? 'long' : ''; + $formatter = new \IntlDateFormatter($this->locale, $xlt[$date], $xlt[$time]); + } else { + $formatter = new \IntlDateFormatter($this->locale, pattern: (new \IntlDatePatternGenerator($this->locale))->getBestPattern($format)); + } + + $res = $formatter->format($value); + $res = preg_replace('~(\d\.) ~', "\$1\u{a0}", $res); + return $res; + } + + + /** + * Formats a number with grouped thousands and optionally decimal digits according to locale. + */ + public function number( + float $number, + string|int $patternOrDecimals = 0, + string $decimalSeparator = '.', + string $thousandsSeparator = ',', + ): string + { + if (is_int($patternOrDecimals) && $patternOrDecimals < 0) { + throw new Latte\RuntimeException('Filter |number: the number of decimal must not be negative'); + } elseif ($this->locale === null || func_num_args() > 2) { + if (is_string($patternOrDecimals)) { + throw new Latte\RuntimeException('Filter |number: using a pattern requires setting a locale via Engine::setLocale().'); + } + return number_format($number, $patternOrDecimals, $decimalSeparator, $thousandsSeparator); + } + + $formatter = new \NumberFormatter($this->locale, \NumberFormatter::DECIMAL); + if (is_string($patternOrDecimals)) { + $formatter->setPattern($patternOrDecimals); + } else { + $formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $patternOrDecimals); + } + return $formatter->format($number); + } + + + /** + * Converts to human-readable file size. + */ + public function bytes(float $bytes, int $precision = 2): string + { + $bytes = round($bytes); + $units = ['B', 'kB', 'MB', 'GB', 'TB', 'PB']; + foreach ($units as $unit) { + if (abs($bytes) < 1024 || $unit === end($units)) { + break; + } + + $bytes /= 1024; + } + + if ($this->locale === null) { + $bytes = (string) round($bytes, $precision); + } else { + $formatter = new \NumberFormatter($this->locale, \NumberFormatter::DECIMAL); + $formatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $precision); + $bytes = $formatter->format($bytes); + } + + return $bytes . ' ' . $unit; + } + + + /** + * Performs a search and replace. + */ + public static function replace( + FilterInfo $info, + string|array $subject, + string|array $search, + string|array|null $replace = null, + ): string + { + $subject = (string) $subject; + if (is_array($search)) { + if (is_array($replace)) { + return strtr($subject, array_combine($search, $replace)); + } elseif ($replace === null && is_string(key($search))) { + return strtr($subject, $search); + } else { + return strtr($subject, array_fill_keys($search, $replace)); + } + } + + return str_replace($search, $replace ?? '', $subject); + } + + + /** + * Perform a regular expression search and replace. + */ + public static function replaceRe(string $subject, string $pattern, string $replacement = ''): string + { + $res = preg_replace($pattern, $replacement, $subject); + if (preg_last_error()) { + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + return $res; + } + + + /** + * The data: URI generator. + */ + public static function dataStream(string $data, ?string $type = null): string + { + $type ??= finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $data); + return 'data:' . ($type ? "$type;" : '') . 'base64,' . base64_encode($data); + } + + + public static function breaklines(string|Stringable|null $s): Html + { + $s = htmlspecialchars((string) $s, ENT_NOQUOTES | ENT_SUBSTITUTE, 'UTF-8'); + return new Html(nl2br($s, false)); + } + + + /** + * Returns a part of string. + */ + public static function substring(string|Stringable|null $s, int $start, ?int $length = null): string + { + $s = (string) $s; + return match (true) { + extension_loaded('mbstring') => mb_substr($s, $start, $length, 'UTF-8'), + extension_loaded('iconv') => iconv_substr($s, $start, $length, 'UTF-8'), + default => throw new Latte\RuntimeException("Filter |substr requires 'mbstring' or 'iconv' extension."), + }; + } + + + /** + * Truncates string to maximal length. + */ + public static function truncate(string|Stringable|null $s, int $length, string $append = "\u{2026}"): string + { + $s = (string) $s; + if (self::strLength($s) > $length) { + $length -= self::strLength($append); + if ($length < 1) { + return $append; + + } elseif (preg_match('#^.{1,' . $length . '}(?=[\s\x00-/:-@\[-`{-~])#us', $s, $matches)) { + return $matches[0] . $append; + + } else { + return self::substring($s, 0, $length) . $append; + } + } + + return $s; + } + + + /** + * Convert to lower case. + */ + public static function lower($s): string + { + return mb_strtolower((string) $s, 'UTF-8'); + } + + + /** + * Convert to upper case. + */ + public static function upper($s): string + { + return mb_strtoupper((string) $s, 'UTF-8'); + } + + + /** + * Convert first character to lower case. + */ + public static function firstLower($s): string + { + $s = (string) $s; + return self::lower(self::substring($s, 0, 1)) . self::substring($s, 1); + } + + + /** + * Convert first character to upper case. + */ + public static function firstUpper($s): string + { + $s = (string) $s; + return self::upper(self::substring($s, 0, 1)) . self::substring($s, 1); + } + + + /** + * Capitalize string. + */ + public static function capitalize($s): string + { + return mb_convert_case((string) $s, MB_CASE_TITLE, 'UTF-8'); + } + + + /** + * Returns length of string or iterable. + */ + public static function length(array|\Countable|\Traversable|string $val): int + { + if (is_array($val) || $val instanceof \Countable) { + return count($val); + } elseif ($val instanceof \Traversable) { + return iterator_count($val); + } else { + return self::strLength($val); + } + } + + + private static function strLength(string $s): int + { + return match (true) { + extension_loaded('mbstring') => mb_strlen($s, 'UTF-8'), + extension_loaded('iconv') => iconv_strlen($s, 'UTF-8'), + default => strlen(@utf8_decode($s)), // deprecated + }; + } + + + /** + * Strips whitespace. + */ + public static function trim(FilterInfo $info, string $s, string $charlist = " \t\n\r\0\x0B\u{A0}"): string + { + $charlist = preg_quote($charlist, '#'); + $s = preg_replace('#^[' . $charlist . ']+|[' . $charlist . ']+$#Du', '', (string) $s); + if (preg_last_error()) { + throw new Latte\RuntimeException(preg_last_error_msg()); + } + + return $s; + } + + + /** + * Pad a string to a certain length with another string. + */ + public static function padLeft($s, int $length, string $append = ' '): string + { + $s = (string) $s; + $length = max(0, $length - self::strLength($s)); + $l = self::strLength($append); + return str_repeat($append, (int) ($length / $l)) . self::substring($append, 0, $length % $l) . $s; + } + + + /** + * Pad a string to a certain length with another string. + */ + public static function padRight($s, int $length, string $append = ' '): string + { + $s = (string) $s; + $length = max(0, $length - self::strLength($s)); + $l = self::strLength($append); + return $s . str_repeat($append, (int) ($length / $l)) . self::substring($append, 0, $length % $l); + } + + + /** + * Reverses string or array. + */ + public static function reverse(string|iterable $val, bool $preserveKeys = false): string|array + { + if (is_array($val)) { + return array_reverse($val, $preserveKeys); + } elseif ($val instanceof \Traversable) { + return array_reverse(iterator_to_array($val), $preserveKeys); + } else { + return iconv('UTF-32LE', 'UTF-8', strrev(iconv('UTF-8', 'UTF-32BE', (string) $val))); + } + } + + + /** + * Chunks items by returning an array of arrays with the given number of items. + */ + public static function batch(iterable $list, int $length, $rest = null): \Generator + { + $batch = []; + foreach ($list as $key => $value) { + $batch[$key] = $value; + if (count($batch) >= $length) { + yield $batch; + $batch = []; + } + } + + if ($batch) { + if ($rest !== null) { + while (count($batch) < $length) { + $batch[] = $rest; + } + } + + yield $batch; + } + } + + + /** + * Sorts elements using the comparison function and preserves the key association. + * @template K + * @template V + * @param iterable $data + * @return iterable + */ + public function sort( + iterable $data, + ?\Closure $comparison = null, + string|int|\Closure|null $by = null, + string|int|\Closure|bool $byKey = false, + ): iterable + { + if ($byKey !== false) { + if ($by !== null) { + throw new \InvalidArgumentException('Filter |sort cannot use both $by and $byKey.'); + } + $by = $byKey === true ? null : $byKey; + } + + if ($comparison) { + } elseif ($this->locale === null) { + $comparison = fn($a, $b) => $a <=> $b; + } else { + $collator = new \Collator($this->locale); + $comparison = fn($a, $b) => is_string($a) && is_string($b) + ? $collator->compare($a, $b) + : $a <=> $b; + } + + $comparison = match (true) { + $by === null => $comparison, + $by instanceof \Closure => fn($a, $b) => $comparison($by($a), $by($b)), + default => fn($a, $b) => $comparison(is_array($a) ? $a[$by] : $a->$by, is_array($b) ? $b[$by] : $b->$by), + }; + + if (is_array($data)) { + $byKey ? uksort($data, $comparison) : uasort($data, $comparison); + return $data; + } + + $pairs = []; + foreach ($data as $key => $value) { + $pairs[] = [$key, $value]; + } + uasort($pairs, fn($a, $b) => $byKey ? $comparison($a[0], $b[0]) : $comparison($a[1], $b[1])); + + return new AuxiliaryIterator($pairs); + } + + + /** + * Groups elements by the element indices and preserves the key association and order. + * @template K + * @template V + * @param iterable $data + * @return iterable> + */ + public static function group(iterable $data, string|int|\Closure $by): iterable + { + $fn = $by instanceof \Closure ? $by : fn($a) => is_array($a) ? $a[$by] : $a->$by; + $keys = $groups = []; + + foreach ($data as $k => $v) { + $groupKey = $fn($v, $k); + if (!$groups || $prevKey !== $groupKey) { + $index = array_search($groupKey, $keys, true); + if ($index === false) { + $index = count($keys); + $keys[$index] = $groupKey; + } + $prevKey = $groupKey; + } + $groups[$index][] = [$k, $v]; + } + + return new AuxiliaryIterator(array_map( + fn($key, $group) => [$key, new AuxiliaryIterator($group)], + $keys, + $groups, + )); + } + + + /** + * Filters elements according to a given $predicate. Maintains original keys. + * @template K + * @template V + * @param iterable $iterable + * @param callable(V, K, iterable): bool $predicate + * @return iterable + */ + public static function filter(iterable $iterable, callable $predicate): iterable + { + foreach ($iterable as $k => $v) { + if ($predicate($v, $k, $iterable)) { + yield $k => $v; + } + } + } + + + /** + * Returns value clamped to the inclusive range of min and max. + */ + public static function clamp(int|float $value, int|float $min, int|float $max): int|float + { + if ($min > $max) { + throw new \InvalidArgumentException("Minimum ($min) is not less than maximum ($max)."); + } + + return min(max($value, $min), $max); + } + + + /** + * Generates URL-encoded query string + */ + public static function query(string|array $data): string + { + return is_array($data) + ? http_build_query($data, '', '&') + : urlencode($data); + } + + + /** + * Is divisible by? + */ + public static function divisibleBy(int $value, int $by): bool + { + return $value % $by === 0; + } + + + /** + * Is odd? + */ + public static function odd(int $value): bool + { + return $value % 2 !== 0; + } + + + /** + * Is even? + */ + public static function even(int $value): bool + { + return $value % 2 === 0; + } + + + /** + * Returns the first element in an array or character in a string, or null if none. + */ + public static function first(string|iterable $value): mixed + { + if (is_string($value)) { + return self::substring($value, 0, 1); + } + + foreach ($value as $item) { + return $item; + } + + return null; + } + + + /** + * Returns the last element in an array or character in a string, or null if none. + */ + public static function last(string|array $value): mixed + { + return is_array($value) + ? ($value ? $value[array_key_last($value)] : null) + : self::substring($value, -1); + } + + + /** + * Extracts a slice of an array or string. + */ + public static function slice( + string|array $value, + int $start, + ?int $length = null, + bool $preserveKeys = false, + ): string|array + { + return is_array($value) + ? array_slice($value, $start, $length, $preserveKeys) + : self::substring($value, $start, $length); + } + + + public static function round(float $value, int $precision = 0): float + { + return round($value, $precision); + } + + + public static function floor(float $value, int $precision = 0): float + { + return floor($value * 10 ** $precision) / 10 ** $precision; + } + + + public static function ceil(float $value, int $precision = 0): float + { + return ceil($value * 10 ** $precision) / 10 ** $precision; + } + + + /** + * Picks random element/char. + */ + public static function random(string|array $values): mixed + { + if (is_string($values)) { + $values = preg_split('//u', $values, -1, PREG_SPLIT_NO_EMPTY); + } + + return $values + ? $values[array_rand($values, 1)] + : null; + } + + + /** + * Sanitizes string for use inside href attribute. + */ + public static function checkUrl($s): string + { + $s = $s instanceof Latte\Runtime\HtmlStringable + ? Latte\Runtime\HtmlHelpers::convertHtmlToText((string) $s) + : (string) $s; + + return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|(?:mailto|tel|sms):.+|[/?#].*|[^:]+)$~Di', $s) ? $s : ''; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php new file mode 100644 index 0000000..e5efc4c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/BlockNode.php @@ -0,0 +1,159 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $tag->outputMode = $tag::OutputRemoveIndentation; + $stream = $tag->parser->stream; + $node = $tag->node = new static; + + if (!$stream->is('|', Token::End)) { + $layer = $tag->parser->tryConsumeTokenBeforeUnquotedString('local') + ? Template::LayerLocal + : $parser->blockLayer; + $stream->tryConsume('#'); + $name = $tag->parser->parseUnquotedStringOrExpression(); + $node->block = new Block($name, $layer, $tag); + + if (!$node->block->isDynamic()) { + $parser->checkBlockIsUnique($node->block); + } + } + + $node->modifier = $tag->parser->parseModifier(); + $noEscape = $node->modifier->removeFilter('noescape'); + if ($noEscape && !$node->modifier->filters) { + throw new CompileException('Filter |noescape is not expected here.', $tag->position); + } + $node->modifier->escape = $node->modifier->filters && !$noEscape; + + [$node->content, $endTag] = yield; + + if ($node->block && $endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if (!$this->block) { + return $this->printFilter($context); + + } elseif ($this->block->isDynamic()) { + return $this->printDynamic($context); + } + + return $this->printStatic($context); + } + + + private function printFilter(PrintContext $context): string + { + return $context->format( + <<<'XX' + ob_start(fn() => '') %line; + try { + (function () { extract(func_get_arg(0)); + %node + })(get_defined_vars()); + } finally { + $ʟ_fi = new LR\FilterInfo(%dump); + echo %modifyContent(ob_get_clean()); + } + + XX, + $this->position, + $this->content, + $context->getEscaper()->export(), + $this->modifier, + ); + } + + + private function printStatic(PrintContext $context): string + { + $this->modifier->escape = $this->modifier->escape || $context->getEscaper()->getState() === Escaper::HtmlAttribute; + $context->addBlock($this->block); + $this->block->content = $this->content->print($context); // must be compiled after is added + + return $context->format( + '$this->renderBlock(%raw, get_defined_vars()' + . ($this->modifier->filters || $this->modifier->escape + ? ', function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }' + : '') + . ') %2.line;', + $context->ensureString($this->block->name, 'Block name'), + $this->modifier, + $this->position, + ); + } + + + private function printDynamic(PrintContext $context): string + { + $context->addBlock($this->block); + $this->block->content = $this->content->print($context); // must be compiled after is added + $escaper = $context->getEscaper(); + $this->modifier->escape = $this->modifier->escape || $escaper->getState() === Escaper::HtmlAttribute; + + return $context->format( + '$this->addBlock($ʟ_nm = %raw, %dump, [[$this, %dump]], %dump); + $this->renderBlock($ʟ_nm, get_defined_vars()' + . ($this->modifier->filters || $this->modifier->escape + ? ', function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }' + : '') + . ');', + $context->ensureString($this->block->name, 'Block name'), + $escaper->export(), + $this->block->method, + $this->block->layer, + $this->modifier, + ); + } + + + public function &getIterator(): \Generator + { + if ($this->block) { + yield $this->block->name; + } + yield $this->modifier; + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php new file mode 100644 index 0000000..19f062a --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/CaptureNode.php @@ -0,0 +1,87 @@ + */ + public static function create(Tag $tag): \Generator + { + $tag->expectArguments(); + $variable = $tag->parser->parseExpression(); + if (!$variable->isWritable()) { + $text = ''; + $i = 0; + while ($token = $tag->parser->stream->peek(--$i)) { + $text = $token->text . $text; + } + + throw new CompileException("It is not possible to write into '$text' in " . $tag->getNotation(), $tag->position); + } + $node = $tag->node = new static; + $node->variable = $variable; + $node->modifier = $tag->parser->parseModifier(); + [$node->content] = yield; + return $node; + } + + + public function print(PrintContext $context): string + { + $escaper = $context->getEscaper(); + return $context->format( + <<<'XX' + ob_start(fn() => '') %line; + try { + %node + } finally { + $ʟ_tmp = %raw; + } + $ʟ_fi = new LR\FilterInfo(%dump); %node = %modifyContent($ʟ_tmp); + + + XX, + $this->position, + $this->content, + $escaper->getState() === Escaper::HtmlText + ? 'ob_get_length() ? new LR\Html(ob_get_clean()) : ob_get_clean()' + : 'ob_get_clean()', + $escaper->export(), + $this->variable, + $this->modifier, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->variable; + yield $this->modifier; + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php new file mode 100644 index 0000000..45822aa --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/ContentTypeNode.php @@ -0,0 +1,87 @@ +expectArguments(); + while (!$tag->parser->stream->consume()->isEnd()); + $type = trim($tag->parser->text); + + if (!$tag->isInHead() && !($tag->htmlElement?->is('script') && str_contains($type, 'html'))) { + throw new CompileException('{contentType} is allowed only in template header.', $tag->position); + } + + $node = new static; + $node->inScript = (bool) $tag->htmlElement; + $node->contentType = match (true) { + str_contains($type, 'html') => ContentType::Html, + str_contains($type, 'xml') => ContentType::Xml, + str_contains($type, 'javascript') => ContentType::JavaScript, + str_contains($type, 'css') => ContentType::Css, + str_contains($type, 'calendar') => ContentType::ICal, + default => ContentType::Text + }; + $parser->setContentType($node->contentType); + + if (strpos($type, '/') && !$tag->htmlElement) { + $node->mimeType = $type; + } + return $node; + } + + + public function print(PrintContext $context): string + { + if ($this->inScript) { + $context->getEscaper()->enterHtmlRaw($this->contentType); + return ''; + } + + $context->beginEscape()->enterContentType($this->contentType); + + return $this->mimeType + ? $context->format( + <<<'XX' + if (empty($this->global->coreCaptured) && in_array($this->getReferenceType(), ['extends', null], true)) { + header(%dump) %line; + } + + XX, + 'Content-Type: ' . $this->mimeType, + $this->position, + ) + : ''; + } + + + public function &getIterator(): \Generator + { + false && yield; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php new file mode 100644 index 0000000..344e1dd --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/CustomFunctionCallNode.php @@ -0,0 +1,48 @@ + */ + public array $args = [], + public ?Position $position = null, + ) { + (function (Php\ArgumentNode ...$args) {})(...$args); + } + + + public function print(PrintContext $context): string + { + return '($this->global->fn->' . $this->name . ')($this, ' . $context->implode($this->args) . ')'; + } + + + public function &getIterator(): \Generator + { + yield $this->name; + foreach ($this->args as &$item) { + yield $item; + } + Helpers::removeNulls($this->args); + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php new file mode 100644 index 0000000..4a1ca99 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/DebugbreakNode.php @@ -0,0 +1,53 @@ +condition = $tag->parser->isEnd() ? null : $tag->parser->parseExpression(); + return $node; + } + + + public function print(PrintContext $context): string + { + if (function_exists($func = 'debugbreak') || function_exists($func = 'xdebug_break')) { + return $context->format( + ($this->condition ? 'if (%1.node) ' : '') . $func . '() %0.line;', + $this->position, + $this->condition, + ); + } + return ''; + } + + + public function &getIterator(): \Generator + { + if ($this->condition) { + yield $this->condition; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php new file mode 100644 index 0000000..e1c7889 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/DefineNode.php @@ -0,0 +1,136 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $tag->expectArguments(); + $layer = $tag->parser->tryConsumeTokenBeforeUnquotedString('local') + ? Template::LayerLocal + : $parser->blockLayer; + $tag->parser->stream->tryConsume('#'); + $name = $tag->parser->parseUnquotedStringOrExpression(); + + $node = $tag->node = new static; + $node->block = new Block($name, $layer, $tag); + if (!$node->block->isDynamic()) { + $parser->checkBlockIsUnique($node->block); + $tag->parser->stream->tryConsume(','); + $node->block->parameters = self::parseParameters($tag); + } + + [$node->content, $endTag] = yield; + if ($endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + + return $node; + } + + + private static function parseParameters(Tag $tag): array + { + $stream = $tag->parser->stream; + $params = []; + while (!$stream->is(Token::End)) { + $type = $tag->parser->parseType(); + + $save = $stream->getIndex(); + $expr = $stream->is(Token::Php_Variable) ? $tag->parser->parseExpression() : null; + if ($expr instanceof VariableNode && is_string($expr->name)) { + $params[] = new ParameterNode($expr, new Scalar\NullNode, $type); + } elseif ( + $expr instanceof AssignNode + && $expr->var instanceof VariableNode + && is_string($expr->var->name) + ) { + $params[] = new ParameterNode($expr->var, $expr->expr, $type); + } else { + $stream->seek($save); + $stream->throwUnexpectedException(addendum: ' in ' . $tag->getNotation()); + } + + if (!$stream->tryConsume(',')) { + break; + } + } + + return $params; + } + + + public function print(PrintContext $context): string + { + return $this->block->isDynamic() + ? $this->printDynamic($context) + : $this->printStatic($context); + } + + + private function printStatic(PrintContext $context): string + { + $context->addBlock($this->block); + $this->block->content = $this->content->print($context); // must be compiled after is added + return ''; + } + + + private function printDynamic(PrintContext $context): string + { + $context->addBlock($this->block); + $this->block->content = $this->content->print($context); // must be compiled after is added + + return $context->format( + '$this->addBlock(%raw, %dump, [[$this, %dump]], %dump);', + $context->ensureString($this->block->name, 'Block name'), + $context->getEscaper()->export(), + $this->block->method, + $this->block->layer, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->block->name; + foreach ($this->block->parameters as &$param) { + yield $param; + } + Helpers::removeNulls($this->block->parameters); + + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php new file mode 100644 index 0000000..e5ec56c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/DoNode.php @@ -0,0 +1,61 @@ +expectArguments(); + + $token = $tag->parser->stream->peek(); + if ($token->is(...self::RefusedKeywords)) { + $tag->parser->throwReservedKeywordException($token); + } + + $node = new static; + $node->expression = $tag->parser->parseExpression(); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + '%node %line;', + $this->expression, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->expression; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php new file mode 100644 index 0000000..0499154 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/DumpNode.php @@ -0,0 +1,58 @@ +expression = $tag->parser->isEnd() + ? null + : $tag->parser->parseExpression(); + return $node; + } + + + public function print(PrintContext $context): string + { + return $this->expression + ? $context->format( + 'Tracy\Debugger::barDump(%node, %dump) %line;', + $this->expression, + $this->expression->print($context), + $this->position, + ) + : $context->format( + "Tracy\\Debugger::barDump(get_defined_vars(), 'variables') %line;", + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + if ($this->expression) { + yield $this->expression; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php new file mode 100644 index 0000000..13a60b1 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/EmbedNode.php @@ -0,0 +1,126 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + if ($tag->isNAttribute()) { + throw new CompileException('Attribute n:embed is not supported.', $tag->position); + } + + $tag->outputMode = $tag::OutputRemoveIndentation; + $tag->expectArguments(); + + $node = $tag->node = new static; + $mode = $tag->parser->tryConsumeTokenBeforeUnquotedString('block', 'file')?->text; + $node->name = $tag->parser->parseUnquotedStringOrExpression(); + $node->mode = $mode ?? ($node->name instanceof StringNode && preg_match('~[\w-]+$~DA', $node->name->value) ? 'block' : 'file'); + $tag->parser->stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + + $prevIndex = $parser->blockLayer; + $parser->blockLayer = $node->layer = count($parser->blocks); + $parser->blocks[$parser->blockLayer] = []; + [$node->blocks] = yield; + + foreach ($node->blocks->children as $child) { + if (!$child instanceof ImportNode && !$child instanceof BlockNode && !$child instanceof TextNode) { + throw new CompileException('Unexpected content inside {embed} tags.', $child->position); + } + } + + $parser->blockLayer = $prevIndex; + return $node; + } + + + public function print(PrintContext $context): string + { + $imports = ''; + foreach ($this->blocks->children as $child) { + if ($child instanceof ImportNode) { + $imports .= $child->print($context); + } else { + $child->print($context); + } + } + + return $this->mode === 'file' + ? $context->format( + <<<'XX' + $this->enterBlockLayer(%dump, get_defined_vars()) %line; %raw + try { + $this->createTemplate(%raw, %node, "embed")->renderToContentType(%dump) %1.line; + } finally { + $this->leaveBlockLayer(); + } + + XX, + $this->layer, + $this->position, + $imports, + $context->ensureString($this->name, 'Template name'), + $this->args, + $context->getEscaper()->export(), + ) + : $context->format( + <<<'XX' + $this->enterBlockLayer(%dump, get_defined_vars()) %line; %raw + $this->copyBlockLayer(); + try { + $this->renderBlock(%raw, %node, %dump) %1.line; + } finally { + $this->leaveBlockLayer(); + } + + XX, + $this->layer, + $this->position, + $imports, + $context->ensureString($this->name, 'Block name'), + $this->args, + $context->getEscaper()->export(), + ); + } + + + public function &getIterator(): \Generator + { + yield $this->name; + yield $this->args; + yield $this->blocks; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php new file mode 100644 index 0000000..1f0988c --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/ExtendsNode.php @@ -0,0 +1,57 @@ +expectArguments(); + $node = new static; + if (!$tag->isInHead()) { + throw new CompileException("{{$tag->name}} must be placed in template head.", $tag->position); + } elseif ($tag->parser->stream->tryConsume('auto')) { + $node->extends = new NullNode; + } elseif ($tag->parser->stream->tryConsume('none')) { + $node->extends = new BooleanNode(false); + } else { + $node->extends = $tag->parser->parseUnquotedStringOrExpression(); + } + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format('$this->parentName = %node;', $this->extends); + } + + + public function &getIterator(): \Generator + { + yield $this->extends; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php new file mode 100644 index 0000000..6671aff --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/FirstLastSepNode.php @@ -0,0 +1,81 @@ + */ + public static function create(Tag $tag): \Generator + { + $node = $tag->node = new static; + $node->name = $tag->name; + $node->width = $tag->parser->isEnd() ? null : $tag->parser->parseExpression(); + + [$node->then, $nextTag] = yield ['else']; + if ($nextTag?->name === 'else') { + $node->elseLine = $nextTag->position; + [$node->else] = yield; + } + + return $node; + } + + + public function print(PrintContext $context): string + { + $cond = match ($this->name) { + 'first' => '$iterator->isFirst', + 'last' => '$iterator->isLast', + 'sep' => '!$iterator->isLast', + }; + return $context->format( + $this->else + ? "if ($cond(%node)) %line { %node } else %line { %node }\n" + : "if ($cond(%node)) %line { %node }\n", + $this->width, + $this->position, + $this->then, + $this->elseLine, + $this->else, + ); + } + + + public function &getIterator(): \Generator + { + if ($this->width) { + yield $this->width; + } + yield $this->then; + if ($this->else) { + yield $this->else; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php new file mode 100644 index 0000000..937ee75 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/ForNode.php @@ -0,0 +1,94 @@ + */ + public static function create(Tag $tag): \Generator + { + $tag->expectArguments(); + $stream = $tag->parser->stream; + $node = $tag->node = new static; + while (!$stream->is(';')) { + $node->init[] = $tag->parser->parseExpression(); + $stream->tryConsume(','); + } + + $stream->consume(';'); + $node->condition = $stream->is(';') ? null : $tag->parser->parseExpression(); + $stream->consume(';'); + while (!$tag->parser->isEnd()) { + $node->next[] = $tag->parser->parseExpression(); + $stream->tryConsume(','); + } + + [$node->content] = yield; + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + <<<'XX' + for (%args; %node; %args) %line { + %node + } + + XX, + $this->init, + $this->condition, + $this->next, + $this->position, + $this->content, + ); + } + + + public function &getIterator(): \Generator + { + foreach ($this->init as &$item) { + yield $item; + } + Helpers::removeNulls($this->init); + + if ($this->condition) { + yield $this->condition; + } + + foreach ($this->next as &$item) { + yield $item; + } + Helpers::removeNulls($this->next); + + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php new file mode 100644 index 0000000..fad872e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/ForeachNode.php @@ -0,0 +1,183 @@ + $value} & {else} + */ +class ForeachNode extends StatementNode +{ + public ExpressionNode $expression; + public ?ExpressionNode $key = null; + public bool $byRef = false; + public ExpressionNode|ListNode $value; + public AreaNode $content; + public ?AreaNode $else = null; + public ?Position $elseLine = null; + public ?bool $iterator = null; + public bool $checkArgs = true; + + + /** @return \Generator */ + public static function create(Tag $tag): \Generator + { + $tag->expectArguments(); + $node = $tag->node = new static; + self::parseArguments($tag->parser, $node); + + $modifier = $tag->parser->parseModifier(); + foreach ($modifier->filters as $filter) { + match ($filter->name->name) { + 'nocheck', 'noCheck' => $node->checkArgs = false, + 'noiterator', 'noIterator' => $node->iterator = false, + default => throw new CompileException('Only modifiers |noiterator and |nocheck are allowed here.', $tag->position), + }; + } + + if ($tag->void) { + $node->content = new NopNode; + return $node; + } + + [$node->content, $nextTag] = yield ['else']; + if ($nextTag?->name === 'else') { + $node->elseLine = $nextTag->position; + [$node->else] = yield; + } + + return $node; + } + + + private static function parseArguments(TagParser $parser, self $node): void + { + $stream = $parser->stream; + $node->expression = $parser->parseExpression(); + $stream->consume('as'); + [$node->key, $node->value, $node->byRef] = $parser->parseForeach(); + } + + + public function print(PrintContext $context): string + { + $content = $this->content->print($context); + $iterator = $this->else || ($this->iterator ?? preg_match('#\$iterator\W|\Wget_defined_vars\W#', $content)); + + if ($this->else) { + $content .= $context->format( + '} if ($iterator->isEmpty()) %line { ', + $this->elseLine, + ) . $this->else->print($context); + } + + if ($iterator) { + return $context->format( + <<<'XX' + foreach ($iterator = $ʟ_it = new Latte\Essential\CachingIterator(%node, $ʟ_it ?? null) as %raw) %line { + %raw + } + $iterator = $ʟ_it = $ʟ_it->getParent(); + + + XX, + $this->expression, + $this->printArgs($context), + $this->position, + $content, + ); + + } else { + return $context->format( + <<<'XX' + foreach (%node as %raw) %line { + %raw + } + + + XX, + $this->expression, + $this->printArgs($context), + $this->position, + $content, + ); + } + } + + + private function printArgs(PrintContext $context): string + { + return ($this->key ? $this->key->print($context) . ' => ' : '') + . ($this->byRef ? '&' : '') + . $this->value->print($context); + } + + + public function &getIterator(): \Generator + { + yield $this->expression; + if ($this->key) { + yield $this->key; + } + yield $this->value; + yield $this->content; + if ($this->else) { + yield $this->else; + } + } + + + /** + * Pass: checks if foreach overrides template variables. + */ + public static function overwrittenVariablesPass(TemplateNode $node): void + { + $vars = []; + (new NodeTraverser)->traverse($node, function (Node $node) use (&$vars) { + if ($node instanceof self && $node->checkArgs) { + foreach ([$node->key, $node->value] as $var) { + if ($var instanceof VariableNode) { + $vars[$var->name][] = $node->position->line; + } + } + } + }); + if ($vars) { + array_unshift($node->head->children, new AuxiliaryNode(fn(PrintContext $context) => $context->format( + <<<'XX' + if (!$this->getReferringTemplate() || $this->getReferenceType() === 'extends') { + foreach (array_intersect_key(%dump, $this->params) as $ʟ_v => $ʟ_l) { + trigger_error("Variable \$$ʟ_v overwritten in foreach on line $ʟ_l"); + } + } + + XX, + array_map(fn($l) => implode(', ', $l), $vars), + ))); + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php new file mode 100644 index 0000000..3e3f048 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/IfChangedNode.php @@ -0,0 +1,141 @@ + */ + public static function create(Tag $tag): \Generator + { + $node = $tag->node = new static; + $node->conditions = $tag->parser->parseArguments(); + + [$node->then, $nextTag] = yield ['else']; + if ($nextTag?->name === 'else') { + $node->elseLine = $nextTag->position; + [$node->else] = yield; + } + + return $node; + } + + + public function print(PrintContext $context): string + { + return $this->conditions->items + ? $this->printExpression($context) + : $this->printCapturing($context); + } + + + private function printExpression(PrintContext $context): string + { + return $this->else + ? $context->format( + <<<'XX' + if (($ʟ_loc[%dump] ?? null) !== ($ʟ_tmp = %node)) { + $ʟ_loc[%0.dump] = $ʟ_tmp; + %node + } else %line { + %node + } + + + XX, + $context->generateId(), + $this->conditions, + $this->then, + $this->elseLine, + $this->else, + ) + : $context->format( + <<<'XX' + if (($ʟ_loc[%dump] ?? null) !== ($ʟ_tmp = %node)) { + $ʟ_loc[%0.dump] = $ʟ_tmp; + %2.node + } + + + XX, + $context->generateId(), + $this->conditions, + $this->then, + ); + } + + + private function printCapturing(PrintContext $context): string + { + return $this->else + ? $context->format( + <<<'XX' + ob_start(fn() => ''); + try %line { + %node + } finally { $ʟ_tmp = ob_get_clean(); } + if (($ʟ_loc[%dump] ?? null) !== $ʟ_tmp) { + echo $ʟ_loc[%2.dump] = $ʟ_tmp; + } else %line { + %node + } + + + XX, + $this->position, + $this->then, + $context->generateId(), + $this->elseLine, + $this->else, + ) + : $context->format( + <<<'XX' + ob_start(fn() => ''); + try %line { + %node + } finally { $ʟ_tmp = ob_get_clean(); } + if (($ʟ_loc[%dump] ?? null) !== $ʟ_tmp) { + echo $ʟ_loc[%2.dump] = $ʟ_tmp; + } + + + XX, + $this->position, + $this->then, + $context->generateId(), + ); + } + + + public function &getIterator(): \Generator + { + yield $this->conditions; + yield $this->then; + if ($this->else) { + yield $this->else; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php new file mode 100644 index 0000000..a772ca0 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/IfContentNode.php @@ -0,0 +1,85 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $node = $tag->node = new static; + $node->id = $parser->generateId(); + [$node->content] = yield; + $node->htmlElement = $tag->htmlElement; + if (!$node->htmlElement->content) { + throw new CompileException("Unnecessary n:ifcontent on empty element <{$node->htmlElement->name}>", $tag->position); + } + return $node; + } + + + public function print(PrintContext $context): string + { + try { + $saved = $this->htmlElement->content; + $else = $this->else ?? new AuxiliaryNode(fn() => ''); + $this->htmlElement->content = new AuxiliaryNode(fn() => <<print($context)} + } finally { + \$ʟ_ifc[$this->id] = rtrim(ob_get_flush()) === ''; + } + + XX); + return << ''); + try { + {$this->content->print($context)} + } finally { + if (\$ʟ_ifc[$this->id] ?? null) { + ob_end_clean(); + {$else->print($context)} + } else { + echo ob_get_clean(); + } + } + + XX; + } finally { + $this->htmlElement->content = $saved; + } + } + + + public function &getIterator(): \Generator + { + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php new file mode 100644 index 0000000..c2ddf96 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/IfNode.php @@ -0,0 +1,185 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $node = $tag->node = new static; + $node->ifset = in_array($tag->name, ['ifset', 'elseifset'], true); + $node->capture = !$tag->isNAttribute() && $tag->name === 'if' && $tag->parser->isEnd(); + $node->position = $tag->position; + if (!$node->capture) { + $node->condition = $node->ifset + ? self::buildCondition($tag->parser) + : $tag->parser->parseExpression(); + } + + [$node->then, $nextTag] = yield $node->capture + ? ['else'] + : ['else', 'elseif', 'elseifset']; + + if ($nextTag?->name === 'else') { + if ($nextTag->parser->stream->is('if')) { + throw new CompileException('Arguments are not allowed in {else}, did you mean {elseif}?', $nextTag->position); + } + $node->elseLine = $nextTag->position; + [$node->else, $nextTag] = yield; + + } elseif ($nextTag?->name === 'elseif' || $nextTag?->name === 'elseifset') { + if ($node->capture) { + throw new CompileException('Tag ' . $nextTag->getNotation() . ' is unexpected here.', $nextTag->position); + } + $node->else = yield from self::create($nextTag, $parser); + } + + if ($node->capture) { + $node->condition = $nextTag->parser->parseExpression(); + } + + return $node; + } + + + private static function buildCondition(TagParser $parser): ExpressionNode + { + $list = []; + do { + $block = $parser->tryConsumeTokenBeforeUnquotedString('block') ?? $parser->stream->tryConsume('#'); + $name = $parser->parseUnquotedStringOrExpression(); + $list[] = $block || $name instanceof StringNode + ? new Expression\AuxiliaryNode( + fn(PrintContext $context, ExpressionNode $name) => '$this->hasBlock(' . $context->ensureString($name, 'Block name') . ')', + [$name], + ) + : new Expression\IssetNode([$name]); + } while ($parser->stream->tryConsume(',')); + + return Expression\BinaryOpNode::nest('&&', ...$list); + } + + + public function print(PrintContext $context): string + { + return $this->capture + ? $this->printCapturing($context) + : $this->printCommon($context); + } + + + private function printCommon(PrintContext $context): string + { + if ($this->else) { + return $context->format( + ($this->else instanceof self + ? "if (%node) %line { %node } else%node\n" + : "if (%node) %line { %node } else %4.line { %3.node }\n"), + $this->condition, + $this->position, + $this->then, + $this->else, + $this->elseLine, + ); + } + return $context->format( + "if (%node) %line { %node }\n", + $this->condition, + $this->position, + $this->then, + ); + } + + + private function printCapturing(PrintContext $context): string + { + if ($this->else) { + return $context->format( + <<<'XX' + ob_start(fn() => '') %line; + try { + %node + ob_start(fn() => '') %line; + try { + %node + } finally { + $ʟ_ifB = ob_get_clean(); + } + } finally { + $ʟ_ifA = ob_get_clean(); + } + echo (%node) ? $ʟ_ifA : $ʟ_ifB %0.line; + + + XX, + $this->position, + $this->then, + $this->elseLine, + $this->else, + $this->condition, + ); + } + + return $context->format( + <<<'XX' + ob_start(fn() => '') %line; + try { + %node + } finally { + $ʟ_ifA = ob_get_clean(); + } + if (%node) %0.line { echo $ʟ_ifA; } + + XX, + $this->position, + $this->then, + $this->condition, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->condition; + yield $this->then; + if ($this->else) { + yield $this->else; + } + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php new file mode 100644 index 0000000..77733cb --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/ImportNode.php @@ -0,0 +1,55 @@ +expectArguments(); + $node = new static; + $node->file = $tag->parser->parseUnquotedStringOrExpression(); + $tag->parser->stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + '$this->createTemplate(%raw, %node? + $this->params, "import")->render() %line;', + $context->ensureString($this->file, 'Template name'), + $this->args, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->file; + yield $this->args; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php new file mode 100644 index 0000000..1a6e167 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeBlockNode.php @@ -0,0 +1,141 @@ +outputMode = $tag::OutputRemoveIndentation; + + $tag->expectArguments(); + $node = new static; + $stream = $tag->parser->stream; + $tag->parser->tryConsumeTokenBeforeUnquotedString('block') ?? $stream->tryConsume('#'); + $node->name = $tag->parser->parseUnquotedStringOrExpression(); + $tokenName = $stream->peek(-1); + + if ($stream->tryConsume('from')) { + $node->from = $tag->parser->parseUnquotedStringOrExpression(); + } + + $stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + $node->modifier = $tag->parser->parseModifier(); + + $node->parent = $tokenName->is('parent'); + if ($node->parent && $node->modifier->filters) { + throw new CompileException('Filters are not allowed in {include parent}', $tag->position); + + } elseif ($node->parent || $tokenName->is('this')) { + $item = $tag->closestTag( + [BlockNode::class, DefineNode::class], + fn($item) => $item->node?->block && !$item->node->block->isDynamic() && $item->node->block->name !== '', + ); + if (!$item) { + throw new CompileException("Cannot include $tokenName->text block outside of any block.", $tag->position); + } + + $node->name = $item->node->block->name; + } + + $node->modifier->escape = !$node->modifier->removeFilter('noescape') && !$node->parent; + $node->blocks = &$parser->blocks; + $node->layer = $parser->blockLayer; + return $node; + } + + + public function print(PrintContext $context): string + { + $contentFilter = $this->modifier->filters + ? $context->format( + 'function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }', + $this->modifier, + ) + : ($this->modifier->escape ? PhpHelpers::dump($context->getEscaper()->export()) : ''); + + return $this->from + ? $this->printBlockFrom($context, $contentFilter) + : $this->printBlock($context, $contentFilter); + } + + + private function printBlock(PrintContext $context, string $contentFilter): string + { + if ($this->name instanceof Scalar\StringNode || $this->name instanceof Scalar\IntegerNode) { + $staticName = (string) $this->name->value; + $block = $this->blocks[$this->layer][$staticName] ?? $this->blocks[Template::LayerLocal][$staticName] ?? null; + } + + return $context->format( + '$this->render' . ($this->parent ? 'ParentBlock' : 'Block') + . '(%raw, %node? + ' + . (isset($block) && !$block->parameters ? 'get_defined_vars()' : '[]') + . '%raw) %line;', + $context->ensureString($this->name, 'Block name'), + $this->args, + $contentFilter ? ", $contentFilter" : '', + $this->position, + ); + } + + + private function printBlockFrom(PrintContext $context, string $contentFilter): string + { + return $context->format( + '$this->createTemplate(%raw, %node? + $this->params, "include")->renderToContentType(%raw, %raw) %line;', + $context->ensureString($this->from, 'Template name'), + $this->args, + $contentFilter, + $context->ensureString($this->name, 'Block name'), + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->name; + if ($this->from) { + yield $this->from; + } + yield $this->args; + yield $this->modifier; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php new file mode 100644 index 0000000..84790d9 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/IncludeFileNode.php @@ -0,0 +1,80 @@ +outputMode = $tag::OutputRemoveIndentation; + + $tag->expectArguments(); + $node = new static; + $tag->parser->tryConsumeTokenBeforeUnquotedString('file'); + $node->file = $tag->parser->parseUnquotedStringOrExpression(); + $node->mode = 'include'; + + $stream = $tag->parser->stream; + if ($stream->tryConsume('with')) { + $stream->consume('blocks'); + $node->mode = 'includeblock'; + } + + $stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + $node->modifier = $tag->parser->parseModifier(); + $node->modifier->escape = !$node->modifier->removeFilter('noescape'); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + '$this->createTemplate(%raw, %node? + $this->params, %dump)->renderToContentType(%raw) %line;', + $context->ensureString($this->file, 'Template name'), + $this->args, + $this->mode, + $this->modifier->filters + ? $context->format( + 'function ($s, $type) { $ʟ_fi = new LR\FilterInfo($type); return %modifyContent($s); }', + $this->modifier, + ) + : PhpHelpers::dump($this->modifier->escape ? $context->getEscaper()->export() : null), + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->file; + yield $this->args; + yield $this->modifier; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php new file mode 100644 index 0000000..aa57c94 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/IterateWhileNode.php @@ -0,0 +1,96 @@ + */ + public static function create(Tag $tag): \Generator + { + $foreach = $tag->closestTag([ForeachNode::class])?->node; + if (!$foreach) { + throw new CompileException("Tag {{$tag->name}} must be inside {foreach} ... {/foreach}.", $tag->position); + } + + $node = $tag->node = new static; + $node->postTest = $tag->parser->isEnd(); + if (!$node->postTest) { + $node->condition = $tag->parser->parseExpression(); + } + + $node->key = $foreach->key; + $node->value = $foreach->value; + [$node->content, $nextTag] = yield; + if ($node->postTest) { + $nextTag->expectArguments(); + $node->condition = $nextTag->parser->parseExpression(); + } + + return $node; + } + + + public function print(PrintContext $context): string + { + $stmt = $context->format( + <<<'XX' + if (!$iterator->hasNext() || !(%node)) { + break; + } + $iterator->next(); + [%node, %node] = [$iterator->key(), $iterator->current()]; + XX, + $this->condition, + $this->key, + $this->value, + ); + + $stmt = $this->postTest + ? $this->content->print($context) . "\n" . $stmt + : $stmt . "\n" . $this->content->print($context); + + return $context->format( + <<<'XX' + do %line { + %raw + } while (true); + + XX, + $this->position, + $stmt, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->condition; + yield $this->content; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php new file mode 100644 index 0000000..4d7526d --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/JumpNode.php @@ -0,0 +1,88 @@ +expectArguments(); + $tag->outputMode = $tag->name === 'exitIf' // to not be in prepare() + ? $tag::OutputRemoveIndentation + : $tag::OutputNone; + + for ( + $parent = $tag->parent; + $parent?->node instanceof IfNode || $parent?->node instanceof IfContentNode; + $parent = $parent->parent + ); + $pnode = $parent?->node; + if (!match ($tag->name) { + 'breakIf', 'continueIf' => $pnode instanceof ForNode || $pnode instanceof ForeachNode || $pnode instanceof WhileNode, + 'skipIf' => $pnode instanceof ForeachNode, + 'exitIf' => !$pnode || $pnode instanceof BlockNode || $pnode instanceof DefineNode, + }) { + throw new CompileException("Tag {{$tag->name}} is unexpected here.", $tag->position); + } + + $last = $parent?->prefix === Tag::PrefixNone + ? $parent->htmlElement->parent + : $parent?->htmlElement; + $el = $tag->htmlElement; + while ($el && $el !== $last) { + $el->breakable = true; + $el = $el->parent; + } + + $node = new static; + $node->type = $tag->name; + $node->condition = $tag->parser->parseExpression(); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + "if (%node) %line %raw\n", + $this->condition, + $this->position, + match ($this->type) { + 'breakIf' => 'break;', + 'continueIf' => 'continue;', + 'skipIf' => '{ $iterator->skipRound(); continue; }', + 'exitIf' => 'return;', + }, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->condition; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php new file mode 100644 index 0000000..912e51f --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/NAttrNode.php @@ -0,0 +1,95 @@ +expectArguments(); + $node = new static; + $node->args = $tag->parser->parseArguments(); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + '$ʟ_tmp = %node; + echo %raw::attrs($ʟ_tmp, %dump, %dump?) %line;', + $this->args, + self::class, + $context->getEscaper()->getContentType() === Latte\ContentType::Xml, + $context->migrationWarnings ?: null, + $this->position, + ); + } + + + public static function attrs(mixed $attrs, bool $xml, bool $migrationWarnings = false): string + { + $attrs = $attrs === [$attrs[0] ?? null] ? $attrs[0] : $attrs; // checks if the value is an array, e.g. n:attr="$attrs" + if (!is_array($attrs)) { + return ''; + } + + $res = ''; + foreach ($attrs as $name => $value) { + $attr = $xml ? self::formatXmlAttribute($name, $value) : self::formatHtmlAttribute($name, $value, $migrationWarnings); + $res .= $attr ? ' ' . $attr : ''; + } + + return $res; + } + + + public static function formatHtmlAttribute(mixed $name, mixed $value, bool $migrationWarnings = false): string + { + LR\HtmlHelpers::validateAttributeName($name); + $type = LR\HtmlHelpers::classifyAttributeType($name); + if ($value === null || ($value === false && $type !== 'data' && $type !== 'aria')) { + return ''; + } elseif ($value === true && $type === '') { + return $name; + } elseif ($migrationWarnings && is_array($value) && $type === 'data') { + LR\HtmlHelpers::triggerMigrationWarning($name, "array value: previously it rendered as $name=\"val1 val2 ...\", now the attribute is JSON-encoded"); + } + return LR\HtmlHelpers::{"format{$type}Attribute"}($name, $value, $migrationWarnings); + } + + + public static function formatXmlAttribute(mixed $name, mixed $value): string + { + LR\XmlHelpers::validateAttributeName($name); + return $value === false ? '' : LR\XmlHelpers::formatAttribute($name, $value); + } + + + public function &getIterator(): \Generator + { + yield $this->args; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php new file mode 100644 index 0000000..244f18e --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/NClassNode.php @@ -0,0 +1,54 @@ +htmlElement->getAttribute('class')) { + throw new CompileException('It is not possible to combine class with n:class.', $tag->position); + } + + $tag->expectArguments(); + $node = new static; + $node->args = $tag->parser->parseArguments(); + return $node; + } + + + public function print(PrintContext $context): string + { + return $context->format( + 'echo ($ʟ_tmp = array_filter(%node)) ? \' class="\' . LR\HtmlHelpers::escapeAttr(implode(" ", array_unique($ʟ_tmp))) . \'"\' : "" %line;', + $this->args, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->args; + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php new file mode 100644 index 0000000..5d6ae05 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/NElseNode.php @@ -0,0 +1,120 @@ + */ + public static function create(Tag $tag): \Generator + { + $node = $tag->node = new static; + if ($tag->name === 'elseif') { + $tag->expectArguments(); + $node->condition = $tag->parser->parseExpression(); + } + [$node->content] = yield; + return $node; + } + + + public function print(PrintContext $context): string + { + throw new \LogicException('Cannot directly print'); + } + + + public function &getIterator(): \Generator + { + if ($this->condition) { + yield $this->condition; + } + yield $this->content; + } + + + public static function processPass(Node $node): void + { + (new NodeTraverser)->traverse($node, function (Node $node) { + if ($node instanceof Nodes\FragmentNode) { + $node->children = self::processFragment($node->children); + } elseif ($node instanceof self) { + self::processFragment([$node]); + } + }); + } + + + private static function processFragment(array $children): array + { + $currentNode = null; + for ($i = 0; isset($children[$i]); $i++) { + $child = $children[$i]; + + if ($child instanceof IfNode + || $child instanceof ForeachNode + || $child instanceof TryNode + || $child instanceof IfChangedNode + || $child instanceof IfContentNode + ) { + $currentNode = $child; + + } elseif ($child instanceof Nodes\TextNode && trim($child->content) === '') { + continue; + + } elseif ($child instanceof self) { + $nElse = $child; + if ($currentNode === null) { + throw new CompileException('n:else must be immediately after n:if, n:foreach etc', $nElse->position); + } elseif ($currentNode->else) { + throw new CompileException('Multiple "else" found.', $nElse->position); + } + + if ($nElse->condition) { + $elseIfNode = new IfNode; + $elseIfNode->condition = $nElse->condition; + $elseIfNode->then = $nElse->content; + $elseIfNode->position = $nElse->position; + $currentNode->else = $elseIfNode; + $currentNode = $elseIfNode; + } else { + $currentNode->else = $nElse->content; + $currentNode = null; + } + + unset($children[$i]); + for ($o = 1; ($children[$i - $o] ?? null) instanceof Nodes\TextNode; $o++) { + unset($children[$i - $o]); + } + } else { + $currentNode = null; + } + } + + return array_values($children); + } +} diff --git a/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php b/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php new file mode 100644 index 0000000..6077ac0 --- /dev/null +++ b/vendor/latte/latte/src/Latte/Essential/Nodes/NTagNode.php @@ -0,0 +1,47 @@ +htmlElement->name)) { + throw new CompileException('Attribute n:tag is not allowed in + + + +<?= $message[0] ?> + + + +
+
+

+ +

+ +

error

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

Requests

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

Presenter

' . $dumper($application->getPresenter()), + ]; + }); + if ( + version_compare(Tracy\Debugger::Version, '2.9.0', '>=') + && version_compare(Tracy\Debugger::Version, '3.0', '<') + ) { + $blueScreen->addFileGenerator(self::generateNewPresenterFileContents(...)); + } + } + + + public static function generateNewPresenterFileContents(string $file, ?string $class = null): ?string + { + if (!$class || !str_ends_with($file, 'Presenter.php')) { + return null; + } + + $res = "checked[$class])) { + return; + } + $this->checked[$class] = true; + + $rc = new \ReflectionClass($class); + if ($rc->getParentClass()) { + $this->checkPresenter($rc->getParentClass()->getName()); + } + + foreach ($rc->getProperties() as $rp) { + if (($rp->getAttributes($attr = Attributes\Parameter::class) || $rp->getAttributes($attr = Attributes\Persistent::class)) + && (!$rp->isPublic() || $rp->isStatic() || $rp->isReadOnly()) + ) { + throw new Nette\InvalidStateException(sprintf('Property %s: attribute %s can be used only with public non-static property.', Reflection::toString($rp), $attr)); + } + } + + $re = $class::formatActionMethod('') . '.|' . $class::formatRenderMethod('') . '.|' . $class::formatSignalMethod('') . '.'; + foreach ($rc->getMethods() as $rm) { + if (preg_match("#^(?!handleInvalidLink)($re)#", $rm->getName()) && (!$rm->isPublic() || $rm->isStatic())) { + throw new Nette\InvalidStateException(sprintf('Method %s: this method must be public non-static.', Reflection::toString($rm))); + } elseif (preg_match('#^createComponent.#', $rm->getName()) && ($rm->isPrivate() || $rm->isStatic())) { + throw new Nette\InvalidStateException(sprintf('Method %s: this method must be non-private non-static.', Reflection::toString($rm))); + } elseif ($rm->getAttributes(Attributes\Requires::class, \ReflectionAttribute::IS_INSTANCEOF) + && !preg_match("#^$re|createComponent.#", $rm->getName()) + ) { + throw new Nette\InvalidStateException(sprintf('Method %s: attribute %s can be used only with action, render, handle or createComponent methods.', Reflection::toString($rm), Attributes\Requires::class)); + } elseif ($rm->getAttributes(Attributes\Deprecated::class) && !preg_match("#^$re#", $rm->getName())) { + throw new Nette\InvalidStateException(sprintf('Method %s: attribute %s can be used only with action, render or handle methods.', Reflection::toString($rm), Attributes\Deprecated::class)); + } + } + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php b/vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php new file mode 100644 index 0000000..efc3d22 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/LatteExtension.php @@ -0,0 +1,178 @@ + Expect::anyOf(true, false, 'all'), + 'macros' => Expect::arrayOf('string'), + 'extensions' => Expect::arrayOf('string|Nette\DI\Definitions\Statement'), + 'templateClass' => Expect::string(), + 'strictTypes' => Expect::bool(false), + 'strictParsing' => Expect::bool(false), + 'phpLinter' => Expect::string(), + 'locale' => Expect::string(), + ]); + } + + + public function loadConfiguration(): void + { + if (!class_exists(Latte\Engine::class)) { + return; + } + + $config = $this->config; + $builder = $this->getContainerBuilder(); + + $latteFactory = $builder->addFactoryDefinition($this->prefix('latteFactory')) + ->setImplement(ApplicationLatte\LatteFactory::class) + ->getResultDefinition() + ->setFactory(Latte\Engine::class) + ->addSetup('setTempDirectory', [$this->tempDir]) + ->addSetup('setAutoRefresh', [$this->debugMode]) + ->addSetup('setStrictTypes', [$config->strictTypes]); + + if (version_compare(Latte\Engine::VERSION, '3', '<')) { + foreach ($config->macros as $macro) { + $this->addMacro($macro); + } + } else { + $latteFactory->addSetup('setStrictParsing', [$config->strictParsing]) + ->addSetup('enablePhpLinter', [$config->phpLinter]) + ->addSetup('setLocale', [$config->locale]); + + $builder->getDefinition($this->prefix('latteFactory')) + ->getResultDefinition() + ->addSetup('?', [$builder::literal('func_num_args() && $service->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(func_get_arg(0)))')]); + + if ($builder->getByType(Nette\Caching\Storage::class)) { + $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class)); + } + if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) { + $this->addExtension(new Statement(Nette\Bridges\FormsLatte\FormsExtension::class)); + } + + foreach ($config->extensions as $extension) { + if ($extension === Latte\Essential\TranslatorExtension::class) { + $extension = new Statement($extension, [new Nette\DI\Definitions\Reference(Nette\Localization\Translator::class)]); + } + $this->addExtension($extension); + } + } + + $builder->addDefinition($this->prefix('templateFactory')) + ->setFactory(ApplicationLatte\TemplateFactory::class) + ->setArguments(['templateClass' => $config->templateClass]); + + if ($this->name === 'latte') { + $builder->addAlias('nette.latteFactory', $this->prefix('latteFactory')); + $builder->addAlias('nette.templateFactory', $this->prefix('templateFactory')); + } + } + + + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + + if ( + $this->debugMode + && ($this->config->debugger ?? $builder->getByType(Tracy\Bar::class)) + && class_exists(Latte\Bridges\Tracy\LattePanel::class) + ) { + $factory = $builder->getDefinition($this->prefix('templateFactory')); + $factory->addSetup([self::class, 'initLattePanel'], [$factory, 'all' => $this->config->debugger === 'all']); + } + } + + + public static function initLattePanel( + Nette\Application\UI\TemplateFactory $factory, + Tracy\Bar $bar, + bool $all = false, + ): void + { + if (!$factory instanceof ApplicationLatte\TemplateFactory) { + return; + } + + $factory->onCreate[] = function (ApplicationLatte\Template $template) use ($bar, $all) { + $control = $template->getLatte()->getProviders()['uiControl'] ?? null; + if ($all || $control instanceof Nette\Application\UI\Presenter) { + $name = $all && $control ? (new \ReflectionObject($control))->getShortName() : ''; + if (version_compare(Latte\Engine::VERSION, '3', '<')) { + $bar->addPanel(new Latte\Bridges\Tracy\LattePanel($template->getLatte(), $name)); + } else { + $template->getLatte()->addExtension(new Latte\Bridges\Tracy\TracyExtension($name)); + } + } + }; + } + + + public function addMacro(string $macro): void + { + $builder = $this->getContainerBuilder(); + $definition = $builder->getDefinition($this->prefix('latteFactory'))->getResultDefinition(); + + if (($macro[0] ?? null) === '@') { + if (str_contains($macro, '::')) { + [$macro, $method] = explode('::', $macro); + } else { + $method = 'install'; + } + + $definition->addSetup('?->onCompile[] = function ($engine) { ?->' . $method . '($engine->getCompiler()); }', ['@self', $macro]); + + } else { + if (!str_contains($macro, '::') && class_exists($macro)) { + $macro .= '::install'; + } + + $definition->addSetup('?->onCompile[] = function ($engine) { ' . $macro . '($engine->getCompiler()); }', ['@self']); + } + } + + + public function addExtension(Statement|string $extension): void + { + $extension = is_string($extension) + ? new Statement($extension) + : $extension; + + $builder = $this->getContainerBuilder(); + $builder->getDefinition($this->prefix('latteFactory')) + ->getResultDefinition() + ->addSetup('addExtension', [$extension]); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php b/vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php new file mode 100644 index 0000000..5142af3 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/PresenterFactoryCallback.php @@ -0,0 +1,65 @@ +container->findByType($class); + if (count($services) > 1) { + $services = array_values(array_filter($services, fn($service) => $this->container->getServiceType($service) === $class)); + if (count($services) > 1) { + throw new Nette\Application\InvalidPresenterException("Multiple services of type $class found: " . implode(', ', $services) . '.'); + } + } + + if (count($services) === 1) { + return $this->container->createService($services[0]); + } + + if ($this->touchToRefresh) { + touch($this->touchToRefresh); + } + + try { + $presenter = $this->container->createInstance($class); + $this->container->callInjects($presenter); + } catch (Nette\DI\MissingServiceException | Nette\DI\ServiceCreationException $e) { + if ($this->touchToRefresh && class_exists($class)) { + throw new \Exception("Refresh your browser. New presenter $class was found.", 0, $e); + } + + throw $e; + } + + if ($presenter instanceof Nette\Application\UI\Presenter && !$presenter->invalidLinkMode) { + $presenter->invalidLinkMode = $this->invalidLinkMode; + } + + return $presenter; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php b/vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php new file mode 100644 index 0000000..3166cb2 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationDI/RoutingExtension.php @@ -0,0 +1,104 @@ + Expect::bool(), + 'routes' => Expect::arrayOf('string'), + 'cache' => Expect::bool(false), + ]); + } + + + public function loadConfiguration(): void + { + if (!$this->config->routes) { + return; + } + + $builder = $this->getContainerBuilder(); + + $router = $builder->addDefinition($this->prefix('router')) + ->setFactory(Nette\Application\Routers\RouteList::class); + + foreach ($this->config->routes as $mask => $action) { + $router->addSetup('$service->addRoute(?, ?)', [$mask, $action]); + } + + if ($this->name === 'routing') { + $builder->addAlias('router', $this->prefix('router')); + } + } + + + public function beforeCompile(): void + { + $builder = $this->getContainerBuilder(); + + if ( + $this->debugMode && + ($this->config->debugger ?? $builder->getByType(Tracy\Bar::class)) && + ($name = $builder->getByType(Nette\Application\Application::class)) && + ($application = $builder->getDefinition($name)) instanceof Definitions\ServiceDefinition + ) { + $application->addSetup('@Tracy\Bar::addPanel', [ + new Definitions\Statement(Nette\Bridges\ApplicationTracy\RoutingPanel::class), + ]); + } + + if (!$builder->getByType(Nette\Routing\Router::class)) { + $builder->addDefinition($this->prefix('router')) + ->setType(Nette\Routing\Router::class) + ->setFactory(Nette\Routing\SimpleRouter::class); + $builder->addAlias('router', $this->prefix('router')); + } + } + + + public function afterCompile(Nette\PhpGenerator\ClassType $class): void + { + if ($this->config->cache) { + $builder = $this->getContainerBuilder(); + $def = $builder->getDefinitionByType(Nette\Routing\Router::class); + $method = $class->getMethod(Nette\DI\Container::getMethodName($def->getName())); + try { + $router = eval($method->getBody()); + if ($router instanceof Nette\Application\Routers\RouteList) { + $router->warmupCache(); + } + + $s = serialize($router); + } catch (\Throwable $e) { + throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e); + } + + $method->setBody('return unserialize(?);', [$s]); + } + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php b/vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php new file mode 100644 index 0000000..c3e6e9c --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/DefaultTemplate.php @@ -0,0 +1,52 @@ +$name = $value; + return $this; + } + + + /** + * Sets all parameters. + */ + public function setParameters(array $params): static + { + return Nette\Utils\Arrays::toObject($params, $this); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php b/vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php new file mode 100644 index 0000000..e6d2c88 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/LatteFactory.php @@ -0,0 +1,21 @@ +outputMode = $tag::OutputRemoveIndentation; + $tag->expectArguments(); + $stream = $tag->parser->stream; + $node = new static; + $node->name = $tag->parser->parseUnquotedStringOrExpression(colon: false); + if ($stream->tryConsume(':')) { + $node->method = $tag->parser->parseExpression(); + } + + $stream->tryConsume(','); + $start = $stream->getIndex(); + $node->args = $tag->parser->parseArguments(); + $start -= $stream->getIndex(); + $depth = $wrap = null; + for (; $start < 0; $start++) { + $token = $stream->peek($start); + match (true) { + $token->is('[') => $depth++, + $token->is(']') => $depth--, + $token->is('=>') && !$depth => $wrap = true, + default => null, + }; + } + + if ($wrap) { + $node->args = new ArrayNode([new ArrayItemNode($node->args)]); + } + + $modifier = $tag->parser->parseModifier(); + foreach ($modifier->filters as $filter) { + match ($filter->name->name) { + 'noescape' => $node->escape = false, + default => throw new Latte\CompileException('Only modifier |noescape is allowed here.', $tag->position), + }; + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if ($this->escape === null && $context->getEscaper()->getState() !== Escaper::HtmlText) { + $this->escape = true; + } + + $method = match (true) { + !$this->method => 'render', + $this->method instanceof StringNode && Strings::match($this->method->value, '#^\w*$#D') => 'render' . ucfirst($this->method->value), + default => "{'render' . " . $this->method->print($context) . '}', + }; + + $fetchCode = $context->format( + $this->name instanceof StringNode + ? '$ʟ_tmp = $this->global->uiControl->getComponent(%node);' + : 'if (!is_object($ʟ_tmp = %node)) $ʟ_tmp = $this->global->uiControl->getComponent($ʟ_tmp);', + $this->name, + ); + + if ($this->escape) { + return $context->format( + <<<'XX' + %raw + if ($ʟ_tmp instanceof Nette\Application\UI\Renderable) $ʟ_tmp->redrawControl(null, false); + ob_start(fn() => ''); + $ʟ_tmp->%raw(%args) %line; + $ʟ_fi = new LR\FilterInfo(%dump); echo %modifyContent(ob_get_clean()); + + + XX, + $fetchCode, + $method, + $this->args, + $this->position, + Latte\ContentType::Html, + new ModifierNode([], $this->escape), + ); + + } else { + return $context->format( + <<<'XX' + %raw + if ($ʟ_tmp instanceof Nette\Application\UI\Renderable) $ʟ_tmp->redrawControl(null, false); + $ʟ_tmp->%raw(%args) %line; + + + XX, + $fetchCode, + $method, + $this->args, + $this->position, + ); + } + } + + + public function &getIterator(): \Generator + { + yield $this->name; + if ($this->method) { + yield $this->method; + } + yield $this->args; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php new file mode 100644 index 0000000..dd1c681 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php @@ -0,0 +1,70 @@ +position->line})", E_USER_DEPRECATED); + $node = $tag->node = new static; + if (!$tag->parser->isEnd()) { + $node->destination = $tag->parser->parseUnquotedStringOrExpression(); + $tag->parser->stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + } + + [$node->content] = yield; + return $node; + } + + + public function print(PrintContext $context): string + { + return $this->destination + ? $context->format( + 'if ($this->global->uiPresenter->isLinkCurrent(%node, %args?)) { %node } ', + $this->destination, + $this->args, + $this->content, + ) + : $context->format( + 'if ($this->global->uiPresenter->getLastCreatedRequestFlag("current")) { %node } ', + $this->content, + ); + } + + + public function &getIterator(): \Generator + { + if ($this->destination) { + yield $this->destination; + yield $this->args; + } + yield $this->content; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php new file mode 100644 index 0000000..1956348 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkBaseNode.php @@ -0,0 +1,83 @@ +expectArguments(); + if (!$tag->isInHead()) { + throw new CompileException("{{$tag->name}} must be placed in template head.", $tag->position); + } + + $node = new static; + $node->base = $tag->parser->parseUnquotedStringOrExpression(); + return $node; + } + + + public function print(PrintContext $context): string + { + return ''; + } + + + public function &getIterator(): \Generator + { + yield $this->base; + } + + + public static function applyLinkBasePass(TemplateNode $node): void + { + $base = NodeHelpers::findFirst($node, fn(Node $node) => $node instanceof self)?->base; + if ($base === null) { + return; + } + + (new NodeTraverser)->traverse($node, function (Node $link) use ($base) { + if ($link instanceof LinkNode) { + if ($link->destination instanceof StringNode && $base instanceof StringNode) { + $link->destination->value = LinkGenerator::applyBase($link->destination->value, $base->value); + } else { + $origDestination = $link->destination; + $link->destination = new AuxiliaryNode( + fn(PrintContext $context) => $context->format( + LinkGenerator::class . '::applyBase(%node, %node)', + $origDestination, + $base, + ), + ); + } + } + }); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php new file mode 100644 index 0000000..e432016 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/LinkNode.php @@ -0,0 +1,92 @@ +outputMode = $tag::OutputKeepIndentation; + $tag->expectArguments(); + $node = new static; + $node->destination = $tag->parser->parseUnquotedStringOrExpression(); + $tag->parser->stream->tryConsume(','); + $node->args = $tag->parser->parseArguments(); + $node->modifier = $tag->parser->parseModifier(); + $node->modifier->escape = true; + $node->modifier->check = false; + $node->mode = $tag->name; + + if ($tag->isNAttribute()) { + // move at the beginning + $node->position = $tag->position; + array_unshift($tag->htmlElement->attributes->children, $node); + return null; + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if ($this->mode === 'href') { + $context->beginEscape()->enterHtmlAttribute(null); + $res = $context->format( + <<<'XX' + echo ' href="'; echo %modify($this->global->uiControl->link(%node, %node?)) %line; echo '"'; + XX, + $this->modifier, + $this->destination, + $this->args, + $this->position, + ); + $context->restoreEscape(); + return $res; + } + + return $context->format( + 'echo %modify(' + . ($this->mode === 'plink' ? '$this->global->uiPresenter' : '$this->global->uiControl') + . '->link(%node, %node?)) %line;', + $this->modifier, + $this->destination, + $this->args, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->destination; + yield $this->args; + yield $this->modifier; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php new file mode 100644 index 0000000..04176f4 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/NNonceNode.php @@ -0,0 +1,37 @@ +global->uiNonce ? " nonce=\"{$this->global->uiNonce}\"" : "";'; + } + + + public function &getIterator(): \Generator + { + false && yield; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php new file mode 100644 index 0000000..b4353f4 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php @@ -0,0 +1,88 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $node = $tag->node = new static; + $name = $tag->parser->parseUnquotedStringOrExpression(); + if ( + $name instanceof Expression\ClassConstantFetchNode + && $name->class instanceof Php\NameNode + && $name->name instanceof Php\IdentifierNode + ) { + $name = new Scalar\StringNode(constant($name->class . '::' . $name->name), $name->position); + } + $node->block = new Block($name, Template::LayerSnippet, $tag); + $parser->checkBlockIsUnique($node->block); + [$node->content, $endTag] = yield; + if ($endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + return $node; + } + + + public function print(PrintContext $context): string + { + $context->addBlock($this->block); + $this->block->content = $context->format( + <<<'XX' + $this->global->snippetDriver->enter(%node, %dump); + try { + %node + } finally { + $this->global->snippetDriver->leave(); + } + + XX, + $this->block->name, + SnippetRuntime::TypeArea, + $this->content, + ); + + return $context->format( + '$this->renderBlock(%node, [], null, %dump) %line;', + $this->block->name, + Template::LayerSnippet, + $this->position, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->block->name; + yield $this->content; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php new file mode 100644 index 0000000..5c7c2b2 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php @@ -0,0 +1,169 @@ + */ + public static function create(Tag $tag, TemplateParser $parser): \Generator + { + $tag->outputMode = $tag::OutputKeepIndentation; + + $node = $tag->node = new static; + $node->htmlElement = $tag->isNAttribute() ? $tag->htmlElement : null; + + if ($tag->parser->isEnd()) { + $name = null; + $node->block = new Block(new Scalar\StringNode(''), Template::LayerSnippet, $tag); + } else { + $name = $tag->parser->parseUnquotedStringOrExpression(); + if ( + $name instanceof Expression\ClassConstantFetchNode + && $name->class instanceof Php\NameNode + && $name->name instanceof Php\IdentifierNode + ) { + $name = new Scalar\StringNode(constant($name->class . '::' . $name->name), $name->position); + } + $node->block = new Block($name, Template::LayerSnippet, $tag); + if (!$node->block->isDynamic()) { + $parser->checkBlockIsUnique($node->block); + } + } + + if ($tag->isNAttribute()) { + if ($tag->prefix !== $tag::PrefixNone) { + throw new CompileException("Use n:snippet instead of {$tag->getNotation()}", $tag->position); + + } elseif ($tag->htmlElement->getAttribute(self::$snippetAttribute)) { + throw new CompileException('Cannot combine HTML attribute ' . self::$snippetAttribute . ' with n:snippet.', $tag->position); + + } elseif (isset($tag->htmlElement->nAttributes['ifcontent'])) { + throw new CompileException('Cannot combine n:ifcontent with n:snippet.', $tag->position); + + } elseif (isset($tag->htmlElement->nAttributes['foreach'])) { + throw new CompileException('Combination of n:snippet with n:foreach is invalid, use n:inner-foreach.', $tag->position); + } + + $tag->replaceNAttribute(new AuxiliaryNode( + fn(PrintContext $context) => "echo ' " . $node->printAttribute($context) . "';", + )); + } + + [$node->content, $endTag] = yield; + if ($endTag && $name instanceof Scalar\StringNode) { + $endTag->parser->stream->tryConsume($name->value); + } + + return $node; + } + + + public function print(PrintContext $context): string + { + if (!$this->block->isDynamic()) { + $context->addBlock($this->block); + } + + if ($this->htmlElement) { + try { + $inner = $this->htmlElement->content; + $this->htmlElement->content = new AuxiliaryNode(fn() => $this->printContent($context, $inner)); + return $this->content->print($context); + } finally { + $this->htmlElement->content = $inner; + } + } else { + return <<printAttribute($context)}>'; + {$this->printContent($context, $this->content)} + echo ''; + XX; + } + } + + + private function printContent(PrintContext $context, AreaNode $inner): string + { + $dynamic = $this->block->isDynamic(); + $res = $context->format( + <<<'XX' + $this->global->snippetDriver->enter(%node, %dump) %line; + try { + %node + } finally { + $this->global->snippetDriver->leave(); + } + + XX, + $dynamic ? new AuxiliaryNode(fn() => '$ʟ_nm') : $this->block->name, + $dynamic ? SnippetRuntime::TypeDynamic : SnippetRuntime::TypeStatic, + $this->position, + $inner, + ); + + if ($dynamic) { + return $res; + } + + $this->block->content = $res; + return $context->format( + '$this->renderBlock(%node, [], null, %dump) %line;', + $this->block->name, + Template::LayerSnippet, + $this->position, + ); + } + + + private function printAttribute(PrintContext $context): string + { + return $context->format( + <<<'XX' + %raw="', htmlspecialchars($this->global->snippetDriver->getHtmlId(%node)), '" + XX, + self::$snippetAttribute, + $this->block->isDynamic() + ? new Expression\AssignNode(new Expression\VariableNode('ʟ_nm'), $this->block->name) + : $this->block->name, + ); + } + + + public function &getIterator(): \Generator + { + yield $this->block->name; + yield $this->content; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php new file mode 100644 index 0000000..151913a --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Nodes/TemplatePrintNode.php @@ -0,0 +1,61 @@ +getParameters(), ' . PhpHelpers::dump($this->template ?? Template::class) . '); exit;'; + } + + + public static function printClass(array $params, string $parentClass): void + { + $bp = new Latte\Essential\Blueprint; + if (!method_exists($bp, 'generateTemplateClass')) { + throw new \LogicException("Please update 'latte/latte' to version 3.0.15 or newer."); + } + + $control = $params['control'] ?? $params['presenter'] ?? null; + $name = 'Template'; + if ($control instanceof UI\Control) { + $name = preg_replace('#(Control|Presenter)$#', '', $control::class) . 'Template'; + unset($params[$control instanceof UI\Presenter ? 'control' : 'presenter']); + } + $class = $bp->generateTemplateClass($params, $name, $parentClass); + $code = (string) $class->getNamespace(); + + $bp->printBegin(); + $bp->printCode($code); + + if ($control instanceof UI\Control) { + $file = dirname((new \ReflectionClass($control))->getFileName()) . '/' . $class->getName() . '.php'; + if (file_exists($file)) { + echo "unsaved, file {$bp->clickableFile($file)} already exists"; + } else { + echo "saved to file {$bp->clickableFile($file)}"; + file_put_contents($file, "printEnd(); + exit; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php b/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php new file mode 100644 index 0000000..f5d62ef --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetBridge.php @@ -0,0 +1,95 @@ +control = $control; + } + + + public function isSnippetMode(): bool + { + return (bool) $this->control->snippetMode; + } + + + public function setSnippetMode($snippetMode) + { + $this->control->snippetMode = $snippetMode; + } + + + public function needsRedraw($name): bool + { + return $this->control->isControlInvalid($name); + } + + + public function markRedrawn($name): void + { + if ($name !== '') { + $this->control->redrawControl($name, false); + } + } + + + public function getHtmlId($name): string + { + return $this->control->getSnippetId($name); + } + + + public function addSnippet($name, $content): void + { + if (!isset($this->payload)) { + $this->payload = $this->control->getPresenter()->getPayload(); + } + + $this->payload->snippets[$this->control->getSnippetId($name)] = $content; + } + + + public function renderChildren(): void + { + $queue = [$this->control]; + do { + foreach (array_shift($queue)->getComponents() as $child) { + if ($child instanceof Renderable) { + if ($child->isControlInvalid()) { + $child->snippetMode = true; + $child->render(); + $child->snippetMode = false; + } + } elseif ($child instanceof Nette\ComponentModel\IContainer) { + $queue[] = $child; + } + } + } while ($queue); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php b/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php new file mode 100644 index 0000000..71867a3 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/SnippetRuntime.php @@ -0,0 +1,144 @@ + */ + private array $stack = []; + private int $nestingLevel = 0; + private bool $renderingSnippets = false; + + private ?\stdClass $payload; + + + public function __construct( + private readonly Control $control, + ) { + } + + + public function enter(string $name, string $type): void + { + if (!$this->renderingSnippets) { + if ($type === self::TypeDynamic && $this->nestingLevel === 0) { + trigger_error('Dynamic snippets are allowed only inside static snippet/snippetArea.', E_USER_WARNING); + } + + $this->nestingLevel++; + return; + } + + $obStarted = false; + if ( + ($this->nestingLevel === 0 && $this->control->isControlInvalid($name)) + || ($type === self::TypeDynamic && ($previous = end($this->stack)) && $previous[1] === true) + ) { + ob_start(fn() => ''); + $this->nestingLevel = $type === self::TypeArea ? 0 : 1; + $obStarted = true; + } elseif ($this->nestingLevel > 0) { + $this->nestingLevel++; + } + + $this->stack[] = [$name, $obStarted]; + if ($name !== '') { + $this->control->redrawControl($name, false); + } + } + + + public function leave(): void + { + if (!$this->renderingSnippets) { + $this->nestingLevel--; + return; + } + + [$name, $obStarted] = array_pop($this->stack); + if ($this->nestingLevel > 0 && --$this->nestingLevel === 0) { + $content = ob_get_clean(); + $this->payload ??= $this->control->getPresenter()->getPayload(); + $this->payload->snippets[$this->control->getSnippetId($name)] = $content; + + } elseif ($obStarted) { // dynamic snippet wrapper or snippet area + ob_end_clean(); + } + } + + + public function getHtmlId(string $name): string + { + return $this->control->getSnippetId($name); + } + + + /** + * @param Block[] $blocks + * @param mixed[] $params + */ + public function renderSnippets(array $blocks, array $params): bool + { + if ($this->renderingSnippets || !$this->control->snippetMode) { + return false; + } + + $this->renderingSnippets = true; + $this->control->snippetMode = false; + foreach ($blocks as $name => $block) { + if (!$this->control->isControlInvalid($name)) { + continue; + } + + $function = reset($block->functions); + $function($params); + } + + $this->control->snippetMode = true; + $this->renderChildren(); + + $this->renderingSnippets = false; + return true; + } + + + private function renderChildren(): void + { + $queue = [$this->control]; + do { + foreach (array_shift($queue)->getComponents() as $child) { + if ($child instanceof Renderable) { + if ($child->isControlInvalid()) { + $child->snippetMode = true; + $child->render(); + $child->snippetMode = false; + } + } elseif ($child instanceof Nette\ComponentModel\IContainer) { + $queue[] = $child; + } + } + } while ($queue); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/Template.php b/vendor/nette/application/src/Bridges/ApplicationLatte/Template.php new file mode 100644 index 0000000..cf7cef9 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/Template.php @@ -0,0 +1,150 @@ +latte; + } + + + /** + * Renders template to output. + */ + public function render(?string $file = null, array $params = []): void + { + Nette\Utils\Arrays::toObject($params, $this); + $this->latte->render($file ?? $this->file, $this); + } + + + /** + * Renders template to output. + */ + public function renderToString(?string $file = null, array $params = []): string + { + Nette\Utils\Arrays::toObject($params, $this); + return $this->latte->renderToString($file ?? $this->file, $this); + } + + + /** + * Renders template to string. + */ + public function __toString(): string + { + return $this->latte->renderToString($this->file, $this->getParameters()); + } + + + /********************* template filters & helpers ****************d*g**/ + + + /** + * Registers run-time filter. + */ + public function addFilter(?string $name, callable $callback): static + { + $this->latte->addFilter($name, $callback); + return $this; + } + + + /** + * Registers run-time function. + */ + public function addFunction(string $name, callable $callback): static + { + $this->latte->addFunction($name, $callback); + return $this; + } + + + /** + * Sets translate adapter. + */ + public function setTranslator(?Nette\Localization\Translator $translator, ?string $language = null): static + { + if (version_compare(Latte\Engine::VERSION, '3', '<')) { + $this->latte->addFilter( + 'translate', + fn(Latte\Runtime\FilterInfo $fi, ...$args): string => $translator === null + ? $args[0] + : $translator->translate(...$args), + ); + } else { + $this->latte->addExtension(new Latte\Essential\TranslatorExtension($translator, $language)); + } + return $this; + } + + + /********************* template parameters ****************d*g**/ + + + /** + * Sets the path to the template file. + */ + public function setFile(string $file): static + { + $this->file = $file; + return $this; + } + + + final public function getFile(): ?string + { + return $this->file; + } + + + /** + * Returns array of all parameters. + */ + final public function getParameters(): array + { + $res = []; + foreach ((new \ReflectionObject($this))->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { + if ($prop->isInitialized($this)) { + $res[$prop->getName()] = $prop->getValue($this); + } + } + + return $res; + } + + + /** + * Prevents unserialization. + */ + final public function __unserialize($_) + { + throw new Nette\NotImplementedException('Object unserialization is not supported by class ' . static::class); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php b/vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php new file mode 100644 index 0000000..f60226a --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -0,0 +1,151 @@ + Occurs when a new template is created */ + public array $onCreate = []; + private string $templateClass; + + + public function __construct( + private readonly LatteFactory $latteFactory, + private readonly ?Nette\Http\IRequest $httpRequest = null, + private readonly ?Nette\Security\User $user = null, + private readonly ?Nette\Caching\Storage $cacheStorage = null, + $templateClass = null, + ) { + if ($templateClass && (!class_exists($templateClass) || !is_a($templateClass, Template::class, true))) { + throw new Nette\InvalidArgumentException("Class $templateClass does not implement " . Template::class . ' or it does not exist.'); + } + + $this->templateClass = $templateClass ?? DefaultTemplate::class; + } + + + /** + * @template T of Template = Template + * @param class-string|null $class + * @return T + */ + public function createTemplate(?UI\Control $control = null, ?string $class = null): UI\Template + { + $class ??= $this->templateClass; + if (!is_a($class, Template::class, allow_string: true)) { + throw new Nette\InvalidArgumentException("Class $class does not implement " . Template::class . ' or it does not exist.'); + } + + $latte = $this->latteFactory->create($control); + $template = new $class($latte); + + if (version_compare(Latte\Engine::VERSION, '3', '<')) { + $this->setupLatte2($latte, $control, $template); + } elseif (!Nette\Utils\Arrays::some($latte->getExtensions(), fn($e) => $e instanceof UIExtension)) { + $latte->addExtension(new UIExtension($control)); + } + + $this->injectDefaultVariables($template, $control); + + Nette\Utils\Arrays::invoke($this->onCreate, $template); + + return $template; + } + + + private function injectDefaultVariables(Template $template, ?UI\Control $control): void + { + $presenter = $control?->getPresenterIfExists(); + $baseUrl = $this->httpRequest + ? rtrim($this->httpRequest->getUrl()->withoutUserInfo()->getBaseUrl(), '/') + : null; + $flashes = $presenter instanceof UI\Presenter && $presenter->hasFlashSession() + ? (array) $presenter->getFlashSession()->get($control->getParameterId('flash')) + : []; + + $vars = [ + 'user' => $this->user, + 'baseUrl' => $baseUrl, + 'basePath' => $baseUrl ? preg_replace('#https?://[^/]+#A', '', $baseUrl) : null, + 'flashes' => $flashes, + 'control' => $control, + 'presenter' => $presenter, + ]; + + foreach ($vars as $key => $value) { + if ($value !== null && property_exists($template, $key)) { + try { + $template->$key = $value; + } catch (\TypeError) { + } + } + } + } + + + private function setupLatte2( + Latte\Engine $latte, + ?UI\Control $control, + Template $template, + ): void + { + if ($latte->onCompile instanceof \Traversable) { + $latte->onCompile = iterator_to_array($latte->onCompile); + } + + array_unshift($latte->onCompile, function (Latte\Engine $latte) use ($control, $template): void { + if ($this->cacheStorage) { + $latte->getCompiler()->addMacro('cache', new Nette\Bridges\CacheLatte\CacheMacro); + } + + UIMacros::install($latte->getCompiler()); + if (class_exists(Nette\Bridges\FormsLatte\FormMacros::class)) { + Nette\Bridges\FormsLatte\FormMacros::install($latte->getCompiler()); + } + + $control?->templatePrepareFilters($template); + }); + + $latte->addProvider('cacheStorage', $this->cacheStorage); + + $presenter = $control?->getPresenterIfExists(); + if ($control) { + $latte->addProvider('uiControl', $control); + $latte->addProvider('uiPresenter', $presenter); + $latte->addProvider('snippetBridge', new SnippetBridge($control)); + if ($presenter) { + $header = $presenter->getHttpResponse()->getHeader('Content-Security-Policy') + ?: $presenter->getHttpResponse()->getHeader('Content-Security-Policy-Report-Only'); + } + + $nonce = $presenter && preg_match('#\s\'nonce-([\w+/]+=*)\'#', (string) $header, $m) ? $m[1] : null; + $latte->addProvider('uiNonce', $nonce); + } + + if ($presenter) { + $latte->addFunction('isLinkCurrent', [$presenter, 'isLinkCurrent']); + $latte->addFunction('isModuleCurrent', [$presenter, 'isModuleCurrent']); + } + + $latte->addFilter('modifyDate', fn($time, $delta, $unit = null) => $time + ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) + : null); + + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php b/vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php new file mode 100644 index 0000000..965d83c --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/UIExtension.php @@ -0,0 +1,141 @@ +control?->getPresenterIfExists(); + return [ + 'modifyDate' => fn($time, $delta, $unit = null) => $time + ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) + : null, + ] + ($presenter ? [ + 'absoluteUrl' => fn(\Stringable|string|null $link): ?string => $link === null + ? null + : $presenter->getHttpRequest()->getUrl()->resolve((string) $link)->getAbsoluteUrl(), + ] : []); + } + + + public function getFunctions(): array + { + if ($presenter = $this->control?->getPresenterIfExists()) { + return [ + 'isLinkCurrent' => $presenter->isLinkCurrent(...), + 'isModuleCurrent' => $presenter->isModuleCurrent(...), + ]; + } + return []; + } + + + public function getProviders(): array + { + $presenter = $this->control?->getPresenterIfExists(); + $httpResponse = $presenter?->getHttpResponse(); + return [ + 'coreParentFinder' => $this->findLayoutTemplate(...), + 'uiControl' => $this->control, + 'uiPresenter' => $presenter, + 'snippetDriver' => $this->control ? new SnippetRuntime($this->control) : null, + 'uiNonce' => $httpResponse ? $this->findNonce($httpResponse) : null, + ]; + } + + + public function getTags(): array + { + return [ + 'n:href' => Nodes\LinkNode::create(...), + 'n:nonce' => Nodes\NNonceNode::create(...), + 'control' => Nodes\ControlNode::create(...), + 'plink' => Nodes\LinkNode::create(...), + 'link' => Nodes\LinkNode::create(...), + 'linkBase' => Nodes\LinkBaseNode::create(...), + 'ifCurrent' => Nodes\IfCurrentNode::create(...), + 'templatePrint' => Nodes\TemplatePrintNode::create(...), + 'snippet' => Nodes\SnippetNode::create(...), + 'snippetArea' => Nodes\SnippetAreaNode::create(...), + 'layout' => $this->createExtendsNode(...), + 'extends' => $this->createExtendsNode(...), + ]; + } + + + public function getPasses(): array + { + return [ + 'snippetRendering' => $this->snippetRenderingPass(...), + 'applyLinkBase' => [Nodes\LinkBaseNode::class, 'applyLinkBasePass'], + ]; + } + + + /** + * Render snippets instead of template in snippet-mode. + */ + public function snippetRenderingPass(TemplateNode $templateNode): void + { + array_unshift($templateNode->main->children, new Latte\Compiler\Nodes\AuxiliaryNode(fn() => <<<'XX' + if ($this->global->snippetDriver?->renderSnippets($this->blocks[self::LayerSnippet], $this->params)) { return; } + + + XX)); + } + + + public static function findLayoutTemplate(Latte\Runtime\Template $template): ?string + { + $presenter = $template->global->uiControl ?? null; + return $presenter instanceof UI\Presenter && !empty($template::Blocks[$template::LayerTop]) + ? $presenter->findLayoutTemplateFile() + : null; + } + + + private function findNonce(Nette\Http\IResponse $httpResponse): ?string + { + $header = $httpResponse->getHeader('Content-Security-Policy') + ?: $httpResponse->getHeader('Content-Security-Policy-Report-Only'); + return preg_match('#\s\'nonce-([\w+/]+=*)\'#', (string) $header, $m) ? $m[1] : null; + } + + + public static function createExtendsNode(Tag $tag): ExtendsNode + { + $auto = $tag->parser->stream->is('auto'); + $node = ExtendsNode::create($tag); + if ($auto) { + $node->extends = new AuxiliaryNode(fn() => '$this->global->uiPresenter->findLayoutTemplateFile()'); + } + return $node; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/UIMacros.php b/vendor/nette/application/src/Bridges/ApplicationLatte/UIMacros.php new file mode 100644 index 0000000..131c300 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/UIMacros.php @@ -0,0 +1,187 @@ +addMacro('control', [$me, 'macroControl']); + + $me->addMacro('href', null, null, fn(MacroNode $node, PhpWriter $writer): string => ' ?> href="macroLink($node, $writer) . ' ?>"addMacro('plink', [$me, 'macroLink']); + $me->addMacro('link', [$me, 'macroLink']); + $me->addMacro('ifCurrent', [$me, 'macroIfCurrent'], '}'); // deprecated; use n:class="$presenter->linkCurrent ? ..." + $me->addMacro('extends', [$me, 'macroExtends']); + $me->addMacro('layout', [$me, 'macroExtends']); + $me->addMacro('nonce', null, null, 'echo $this->global->uiNonce ? " nonce=\"{$this->global->uiNonce}\"" : "";'); + $me->addMacro('templatePrint', [$me, 'macroTemplatePrint'], null, null, self::ALLOWED_IN_HEAD); + } + + + /** + * Initializes before template parsing. + */ + public function initialize(): void + { + $this->extends = false; + } + + + /** + * Finishes template parsing. + * @return array(prolog, epilog) + */ + public function finalize() + { + if ($this->printTemplate) { + return ["Nette\\Bridges\\ApplicationLatte\\UIRuntime::printClass(\$this, $this->printTemplate); exit;"]; + } + + return [$this->extends . 'Nette\Bridges\ApplicationLatte\UIRuntime::initialize($this, $this->parentName, $this->blocks);']; + } + + + /********************* macros ****************d*g**/ + + + /** + * {control name[:method] [params]} + */ + public function macroControl(MacroNode $node, PhpWriter $writer) + { + if ($node->context !== [Latte\Compiler::CONTENT_HTML, Latte\Compiler::CONTEXT_HTML_TEXT]) { + $escapeMod = Latte\Helpers::removeFilter($node->modifiers, 'noescape') ? '' : '|escape'; + } + + if ($node->modifiers) { + trigger_error('Modifiers are deprecated in ' . $node->getNotation(), E_USER_DEPRECATED); + } + + $node->modifiers .= $escapeMod ?? ''; + + $words = $node->tokenizer->fetchWords(); + if (!$words) { + throw new CompileException('Missing control name in {control}'); + } + + $name = $writer->formatWord($words[0]); + $method = ucfirst($words[1] ?? ''); + $method = Strings::match($method, '#^\w*$#D') + ? "render$method" + : "{\"render$method\"}"; + + $tokens = $node->tokenizer; + $pos = $tokens->position; + $wrap = false; + while ($tokens->nextToken()) { + if ($tokens->isCurrent('=>', '(expand)') && !$tokens->depth) { + $wrap = true; + break; + } + } + + $tokens->position = $pos; + $param = $wrap ? $writer->formatArray() : $writer->formatArgs(); + + return "/* line $node->startLine */ " + . ($name[0] === '$' ? "if (is_object($name)) \$_tmp = $name; else " : '') + . '$_tmp = $this->global->uiControl->getComponent(' . $name . '); ' + . 'if ($_tmp instanceof Nette\Application\UI\Renderable) $_tmp->redrawControl(null, false); ' + . ($node->modifiers === '' + ? "\$_tmp->$method($param);" + : $writer->write( + "ob_start(fn() => null); \$_tmp->$method($param); \$ʟ_fi = new LR\\FilterInfo(%var); echo %modifyContent(ob_get_clean());", + Latte\Engine::CONTENT_HTML, + ) + ); + } + + + /** + * {link destination [,] [params]} + * {plink destination [,] [params]} + * n:href="destination [,] [params]" + */ + public function macroLink(MacroNode $node, PhpWriter $writer) + { + $node->modifiers = preg_replace('#\|safeurl\s*(?=\||$)#Di', '', $node->modifiers); + return $writer->using($node, $this->getCompiler()) + ->write( + 'echo %escape(%modify(' + . ($node->name === 'plink' ? '$this->global->uiPresenter' : '$this->global->uiControl') + . '->link(%node.word, %node.array?)))' + . ($node->startLine ? " /* line $node->startLine */;" : ';'), + ); + } + + + /** + * {ifCurrent destination [,] [params]} + */ + public function macroIfCurrent(MacroNode $node, PhpWriter $writer) + { + if ($node->modifiers) { + throw new CompileException('Modifiers are not allowed in ' . $node->getNotation()); + } + + return $writer->write( + $node->args + ? 'if ($this->global->uiPresenter->isLinkCurrent(%node.word, %node.array?)) {' + : 'if ($this->global->uiPresenter->getLastCreatedRequestFlag("current")) {', + ); + } + + + /** + * {extends auto} + */ + public function macroExtends(MacroNode $node, PhpWriter $writer) + { + if ($node->modifiers || $node->parentNode || $node->args !== 'auto') { + return $this->extends = false; + } + + $this->extends = $writer->write('$this->parentName = $this->global->uiPresenter->findLayoutTemplateFile();'); + } + + + /** + * {templatePrint [parentClass | default]} + */ + public function macroTemplatePrint(MacroNode $node): void + { + if ($node->modifiers) { + throw new CompileException('Modifiers are not allowed in ' . $node->getNotation()); + } + + $this->printTemplate = var_export($node->tokenizer->fetchWord() ?: null, true); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php b/vendor/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php new file mode 100644 index 0000000..ace3af7 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationLatte/UIRuntime.php @@ -0,0 +1,84 @@ +global; + $blocks = array_filter(array_keys($blocks), fn(string $s): bool => $s[0] !== '_'); + if ( + $parentName === null + && $blocks + && !$template->getReferringTemplate() + && ($providers->uiControl ?? null) instanceof Nette\Application\UI\Presenter + ) { + $parentName = $providers->uiControl->findLayoutTemplateFile(); + } + } + + + public static function printClass(Latte\Runtime\Template $template, ?string $parent = null): void + { + $blueprint = new Latte\Runtime\Blueprint; + $name = 'Template'; + $params = $template->getParameters(); + $control = $params['control'] ?? $params['presenter'] ?? null; + if ($control) { + $name = preg_replace('#(Control|Presenter)$#', '', $control::class) . 'Template'; + unset($params[$control instanceof Presenter ? 'control' : 'presenter']); + } + + if ($parent) { + if (!class_exists($parent)) { + $blueprint->printHeader("{templatePrint}: Class '$parent' doesn't exist."); + return; + } + + $params = array_diff_key($params, get_class_vars($parent)); + } + + $funcs = array_diff_key((array) $template->global->fn, (new Latte\Runtime\Defaults)->getFunctions()); + unset($funcs['isLinkCurrent'], $funcs['isModuleCurrent']); + + $namespace = new Php\PhpNamespace(Php\Helpers::extractNamespace($name)); + $class = $namespace->addClass(Php\Helpers::extractShortName($name)); + $class->setExtends($parent ?: Template::class); + if (!$parent) { + $class->addTrait(Nette\SmartObject::class); + } + + $blueprint->addProperties($class, $params, true); + $blueprint->addFunctions($class, $funcs); + + $end = $blueprint->printCanvas(); + $blueprint->printHeader('Native types'); + $blueprint->printCode((string) $namespace); + + $blueprint->addProperties($class, $params, false); + + $blueprint->printHeader('phpDoc types'); + $blueprint->printCode((string) $namespace); + echo $end; + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php b/vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php new file mode 100644 index 0000000..bbfd167 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/RoutingPanel.php @@ -0,0 +1,145 @@ +routes = $this->analyse( + $this->router instanceof Routing\RouteList + ? $this->router + : (new Routing\RouteList)->add($this->router), + $this->httpRequest, + ); + return Nette\Utils\Helpers::capture(function () { + $matched = $this->matched; + require __DIR__ . '/dist/tab.phtml'; + }); + } + + + /** + * Renders panel. + */ + public function getPanel(): string + { + return Nette\Utils\Helpers::capture(function () { + $matched = $this->matched; + $routes = $this->routes; + $source = $this->matched ? $this->findSource() : null; + $url = $this->httpRequest->getUrl(); + $method = $this->httpRequest->getMethod(); + require __DIR__ . '/dist/panel.phtml'; + }); + } + + + private function analyse(Routing\RouteList $router, ?Nette\Http\IRequest $httpRequest): array + { + $res = [ + 'path' => $router->getPath(), + 'domain' => $router->getDomain(), + 'module' => ($router instanceof Nette\Application\Routers\RouteList ? $router->getModule() : ''), + 'routes' => [], + ]; + $httpRequest = $httpRequest + ? (fn() => $this->prepareRequest($httpRequest))->bindTo($router, Routing\RouteList::class)() + : null; + $flags = $router->getFlags(); + + foreach ($router->getRouters() as $i => $innerRouter) { + if ($innerRouter instanceof Routing\RouteList) { + $res['routes'][] = $this->analyse($innerRouter, $httpRequest); + continue; + } + + $matched = $flags[$i] & $router::ONE_WAY ? 'oneway' : 'no'; + $params = $e = null; + try { + if ( + $httpRequest + && ($params = $innerRouter->match($httpRequest)) !== null + && ($params = (fn() => $this->completeParameters($params))->bindTo($router, Routing\RouteList::class)()) !== null + ) { + $matched = 'may'; + if ($this->matched === null) { + $this->matched = $params; + $matched = 'yes'; + } + } + } catch (\Throwable $e) { + $matched = 'error'; + } + + $res['routes'][] = (object) [ + 'matched' => $matched, + 'class' => $innerRouter::class, + 'defaults' => $innerRouter instanceof Routing\Route || $innerRouter instanceof Routing\SimpleRouter ? $innerRouter->getDefaults() : [], + 'mask' => $innerRouter instanceof Routing\Route ? $innerRouter->getMask() : null, + 'params' => $params, + 'error' => $e, + ]; + } + return $res; + } + + + private function findSource(): \ReflectionClass|\ReflectionMethod|string|null + { + $params = $this->matched; + $presenter = $params['presenter'] ?? ''; + try { + $class = $this->presenterFactory->getPresenterClass($presenter); + } catch (Nette\Application\InvalidPresenterException) { + if ($this->presenterFactory instanceof Nette\Application\PresenterFactory) { + return $this->presenterFactory->formatPresenterClass($presenter); + } + return null; + } + + if (is_a($class, Nette\Application\UI\Presenter::class, allow_string: true)) { + $rc = $class::getReflection(); + if (isset($params[Presenter::SignalKey])) { + return $rc->getSignalMethod($params[Presenter::SignalKey]); + } elseif (isset($params[Presenter::ActionKey]) + && ($method = $rc->getActionRenderMethod($params[Presenter::ActionKey])) + ) { + return $method; + } + } + + return new \ReflectionClass($class); + } +} diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml new file mode 100644 index 0000000..873d1d5 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/panel.phtml @@ -0,0 +1,185 @@ + + + + +

+ no route + +: + + + +! + +

+ +
+
+

+ + + getBaseUrl()) ?> +&', '?'], htmlspecialchars($url->getRelativeUrl())) ?> + +

+ +

+ (class not found)

+

getName() : $source->getDeclaringClass()->getName() . '::' . $source->getName() . '()') ?> +

+
+ +
+

No routes defined.

+
+
+
+
Mask / Class
+
Defaults
+
Matched as
+
+ +
+
+ + domain = + + + + module = + + +
+
+ +
+
+ '✓', 'may' => '≈', 'no' => '', 'oneway' => '⛔', 'error' => '❌'][$route->matched]) ?> + +
+ +
+ + + + + + mask) ? str_replace(['/', '-'], ['/', '-'], htmlspecialchars($route->mask)) : str_replace('\\', '\\', htmlspecialchars($route->class)) ?> + + +
+ +
+ +defaults as $key => $value): ?> + =  + +
true, Dumper::LIVE => true]) ?> + + +
+
+ +
+params): ?> +params ?> +: + +
+ $value): ?> + =  + +
true, Dumper::LIVE => true]) ?> + + +
+error): ?> error->getMessage()) ?> + +
+
+ +
+
+
diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml new file mode 100644 index 0000000..c68ce00 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/dist/tab.phtml @@ -0,0 +1,20 @@ + + + + + + + + no route + +: + + + +! + + + diff --git a/vendor/nette/application/src/Bridges/ApplicationTracy/panel.latte b/vendor/nette/application/src/Bridges/ApplicationTracy/panel.latte new file mode 100644 index 0000000..580cbb2 --- /dev/null +++ b/vendor/nette/application/src/Bridges/ApplicationTracy/panel.latte @@ -0,0 +1,181 @@ +{use Nette\Application\UI\Presenter} +{use Tracy\Dumper} + + + +

+ {if $matched === null} + no route + {elseif isset($matched[Presenter::PresenterKey])} + {$matched[Presenter::PresenterKey]}:{$matched[Presenter::ActionKey] ?? Presenter::DefaultAction} + {if isset($matched[Presenter::SignalKey])}{$matched[Presenter::SignalKey]}!{/if} + {/if} +

+ +
+
+

+ {$method} + {$url->getBaseUrl()}{str_replace(['&', '?'], ['&', '?'], htmlspecialchars($url->getRelativeUrl()))|noescape} +

+ + {if is_string($source)} +

{$source} (class not found)

+ {elseif $source} +

{$source instanceof ReflectionClass ? $source->getName() : $source->getDeclaringClass()->getName() . '::' . $source->getName() . '()'}

+ {/if} +
+ +
+ {if empty($routes)} +

No routes defined.

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

Nette Forms basic example

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

Form was submitted and successfully validated

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

Nette Forms & Bootstrap v4 rendering example

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

Form was submitted and successfully validated

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

Nette Forms & Bootstrap v5 rendering example

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

Form was submitted and successfully validated

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

Nette Forms containers example

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

Form was submitted and successfully validated

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

Nette Forms custom control example

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

Form was submitted and successfully validated

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

Nette Forms custom rendering example

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

Form was submitted and successfully validated

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

Nette Forms custom validator example

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

Form was submitted and successfully validated

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

Nette Forms and HTML5

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

Form was submitted and successfully validated

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

Nette Forms & Bootstrap v5 rendering example

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

Form was submitted and successfully validated

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

Nette Forms live validation example

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

Form was submitted and successfully validated

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

Nette Forms localization example

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

Form was submitted and successfully validated

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

Nette Forms manual form rendering

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

+ + + + + + + <?= Helpers::escapeHtml($title . ': ' . $exception->getMessage() . $code) ?> + + 1): ?> + + + + + + + + + + + +> +'use strict'; + +Tracy.BlueScreen.init(); + + + diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-cli.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-cli.phtml new file mode 100644 index 0000000..6d06e40 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-cli.phtml @@ -0,0 +1,36 @@ + +
+ + +
+

Process ID

+ +
php
+ + + +

Arguments

+
+ + $v): ?> + + +
+
+ +
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-environment.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-environment.phtml new file mode 100644 index 0000000..866ec89 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-environment.phtml @@ -0,0 +1,103 @@ + +
+ + +
+ +
+ + + +
+
+ + $v): ?> + + +
+
+ + + +
+
+ + $v): ?> + + +
Nette Session' : $dump($v, $k) ?>
+
+ + + +

Nette Session

+
+ + $v): ?> + + +
+
+ +
+ + + + + +
+ + $v): ?> + + +
+
+ + + +
+ renderPhpInfo() ?> + +
+ + + +
+ 10]) ?> +
+ +
+
+
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-causedBy.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-causedBy.phtml new file mode 100644 index 0000000..8807bf0 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-causedBy.phtml @@ -0,0 +1,29 @@ +getPrevious(); +if (!$ex || in_array($ex, $exceptions, true)) { + return; +} +$exceptions[] = $ex; +?> + +
+ + +
+ + +
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-exception.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-exception.phtml new file mode 100644 index 0000000..104edd4 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception-exception.phtml @@ -0,0 +1,21 @@ + +
+ +
+ +
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception.phtml new file mode 100644 index 0000000..fba0627 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-exception.phtml @@ -0,0 +1,72 @@ + + + +renderPanels($ex) as $panel): ?> +
+ + +
+ panel ?> +
+
+ + + +
+
+
+ + +
+
+ +
+ + +
+ +
+ + + +
+ +
+ +
+
+
+
+ + + + + + + diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-header.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-header.phtml new file mode 100644 index 0000000..f4ab19f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-header.phtml @@ -0,0 +1,35 @@ +getSeverity()) + : get_debug_type($ex); +$code = $ex->getCode() ? ' #' . $ex->getCode() : ''; + +?> +
+ getMessage()): ?>

+ + +

formatMessage($ex) ?: Helpers::escapeHtml($title . $code) ?> + + > + +

+ + getPrevious()): ?> + + +
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-http.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-http.phtml new file mode 100644 index 0000000..000ef1a --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-http.phtml @@ -0,0 +1,124 @@ + +
+ + +
+ +
+ + +
+ +
+

+ + +
+ + $v): ?> + + +
+
+ + + +

$_GET

+ +

empty

+ +
+ + $v): ?> + + +
+
+ + + + + + +

$_POST

+

empty

+ +

POST (preview)

+ + + +

$_POST

+
+ + $v): ?> + + +
+
+ + + +

$_COOKIE

+ +

empty

+ +
+ + $v): ?> + + +
+
+ +
+ + +
+

Code:

+ +
+ + + + +
+
+ +

no headers

+ + + + +

Headers have been sent, output started at source

+
+ +

Headers have been sent

+ +

Headers were not sent at the time the exception was thrown

+ +
+
+
+
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-lastMutedError.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-lastMutedError.phtml new file mode 100644 index 0000000..a4f79f7 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-lastMutedError.phtml @@ -0,0 +1,29 @@ + +
+ +
+ +

:

+

Note: the last muted error may have nothing to do with the thrown exception.

+ + +

+
+ +

inner-code

+ +
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml new file mode 100644 index 0000000..74b3744 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml @@ -0,0 +1,92 @@ + + +
+ + +
+
+ $row): ?> + + +
+ + + + inner-code + + +
+ +
+ + +  + + +
+ + +
+ + + +
+ + +
+
+ +
+ +
+ +
+
+
+ + + + + + + +getParameters(); + } catch (\Exception) { + $params = []; + } + foreach ($row['args'] as $k => $v) { + $argName = isset($params[$k]) && !$params[$k]->isVariadic() ? $params[$k]->name : $k; + echo '\n"; + } +?> +
', Helpers::escapeHtml((is_string($argName) ? '$' : '#') . $argName), ''; + echo $dump($v, (string) $argName); + echo "
+ +
+ + +
+
+
diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-exception.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-exception.phtml new file mode 100644 index 0000000..7f578cc --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-exception.phtml @@ -0,0 +1,38 @@ +getTrace(); +if (in_array($stack[0]['class'] ?? null, [DevelopmentStrategy::class, ProductionStrategy::class], true)) { + array_shift($stack); +} +if (($stack[0]['class'] ?? null) === Debugger::class && in_array($stack[0]['function'], ['shutdownHandler', 'errorHandler'], true)) { + array_shift($stack); +} + +$expanded = null; +if ( + (!$ex instanceof \ErrorException || in_array($ex->getSeverity(), [E_USER_NOTICE, E_USER_WARNING, E_USER_DEPRECATED], true)) + && $this->isCollapsed($ex->getFile()) +) { + foreach ($stack as $key => $row) { + if (isset($row['file']) && !$this->isCollapsed($row['file'])) { + $expanded = $key; + break; + } + } +} + +$file = $ex->getFile(); +$line = $ex->getLine(); + +require __DIR__ . '/section-stack-sourceFile.phtml'; +require __DIR__ . '/section-stack-callStack.phtml'; diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-fiber.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-fiber.phtml new file mode 100644 index 0000000..4427be8 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-fiber.phtml @@ -0,0 +1,16 @@ +getTrace(); +$expanded = 0; + +require __DIR__ . '/section-stack-callStack.phtml'; diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-generator.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-generator.phtml new file mode 100644 index 0000000..60aa6fc --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-generator.phtml @@ -0,0 +1,21 @@ +getTrace(); +$expanded = null; +$execGenerator = $ref->getExecutingGenerator(); +$refExec = new \ReflectionGenerator($execGenerator); +$file = $refExec->getExecutingFile(); +$line = $refExec->getExecutingLine(); + +require __DIR__ . '/section-stack-sourceFile.phtml'; +require __DIR__ . '/section-stack-callStack.phtml'; diff --git a/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml new file mode 100644 index 0000000..492a526 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/BlueScreen/assets/section-stack-sourceFile.phtml @@ -0,0 +1,46 @@ + + +
+ + +
+ +
+ + +
+
+

File:

+ +
+ +
+

File:

+ +
+
+
+ +

File:

+ + + +
+
diff --git a/vendor/tracy/tracy/src/Tracy/Debugger/Debugger.php b/vendor/tracy/tracy/src/Tracy/Debugger/Debugger.php new file mode 100644 index 0000000..23b3c2f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Debugger/Debugger.php @@ -0,0 +1,623 @@ +initialize(); + self::dispatch(); + + if (self::$enabled) { + return; + } + + register_shutdown_function([self::class, 'shutdownHandler']); + set_exception_handler(function (\Throwable $e) { + self::exceptionHandler($e); + exit(255); + }); + set_error_handler([self::class, 'errorHandler']); + + foreach ([ + 'Bar/Bar', + 'Bar/DefaultBarPanel', + 'BlueScreen/BlueScreen', + 'BlueScreen/CodeHighlighter', + 'Dumper/Describer', + 'Dumper/Dumper', + 'Dumper/Exposer', + 'Dumper/Renderer', + 'Dumper/Value', + 'Logger/Logger', + 'Session/SessionStorage', + 'Session/FileSession', + 'Session/NativeSession', + 'Helpers', + ] as $path) { + require_once dirname(__DIR__) . "/$path.php"; + } + + self::$enabled = true; + } + + + public static function dispatch(): void + { + if ( + !Helpers::isCli() + && self::getStrategy()->sendAssets() + ) { + self::$showBar = false; + exit; + } + } + + + /** + * Renders loading + + + +Server Error + + + +
+
+

Server Error

+ +

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

+ +

error 500 |
Tracy is unable to log error.

+
+
+ +> + document.body.insertBefore(document.getElementById('tracy-error'), document.body.firstChild); + diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Describer.php b/vendor/tracy/tracy/src/Tracy/Dumper/Describer.php new file mode 100644 index 0000000..57fbed9 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Describer.php @@ -0,0 +1,363 @@ + */ + public array $resourceExposers = []; + + /** @var array */ + public array $objectExposers = []; + + /** @var array */ + public array $enumProperties = []; + + /** @var (int|\stdClass)[] */ + public array $references = []; + + + public function describe(mixed $var): \stdClass + { + uksort($this->objectExposers, fn($a, $b): int => $b === '' || (class_exists($a, false) && is_subclass_of($a, $b)) ? -1 : 1); + + try { + return (object) [ + 'value' => $this->describeVar($var), + 'snapshot' => $this->snapshot, + 'location' => $this->location ? self::findLocation() : null, + ]; + + } finally { + $free = [[], []]; + $this->snapshot = &$free[0]; + $this->references = &$free[1]; + } + } + + + private function describeVar(mixed $var, int $depth = 0, ?int $refId = null): mixed + { + if ($var === null || is_bool($var)) { + return $var; + } + + $m = 'describe' . explode(' ', gettype($var))[0]; + return $this->$m($var, $depth, $refId); + } + + + private function describeInteger(int $num): Value|int + { + return $num <= self::JsSafeInteger && $num >= -self::JsSafeInteger + ? $num + : new Value(Value::TypeNumber, "$num"); + } + + + private function describeDouble(float $num): Value|float + { + if (is_nan($num)) { + return new Value(Value::TypeNumber, 'NAN'); + } elseif (is_infinite($num)) { + return new Value(Value::TypeNumber, $num < 0 ? '-INF' : 'INF'); + } + + $js = json_encode($num); + return strpos($js, '.') + ? $num + : new Value(Value::TypeNumber, "$js.0"); // to distinct int and float in JS + } + + + private function describeString(string $s, int $depth = 0): Value|string + { + $encoded = Helpers::encodeString($s, $depth ? $this->maxLength : null); + if ($encoded === $s) { + return $encoded; + } elseif (Helpers::isUtf8($s)) { + return new Value(Value::TypeStringHtml, $encoded, Helpers::utf8Length($s)); + } else { + return new Value(Value::TypeBinaryHtml, $encoded, strlen($s)); + } + } + + + private function describeArray(array $arr, int $depth = 0, ?int $refId = null): Value|array + { + if ($refId) { + $res = new Value(Value::TypeRef, 'p' . $refId); + $value = &$this->snapshot[$res->value]; + if ($value && $value->depth <= $depth) { + return $res; + } + + $value = new Value(Value::TypeArray); + $value->id = $res->value; + $value->depth = $depth; + if ($this->maxDepth && $depth >= $this->maxDepth) { + $value->length = count($arr); + return $res; + } elseif ($depth && $this->maxItems && count($arr) > $this->maxItems) { + $value->length = count($arr); + $arr = array_slice($arr, 0, $this->maxItems, preserve_keys: true); + } + + $items = &$value->items; + + } elseif ($arr && $this->maxDepth && $depth >= $this->maxDepth) { + return new Value(Value::TypeArray, null, count($arr)); + + } elseif ($depth && $this->maxItems && count($arr) > $this->maxItems) { + $res = new Value(Value::TypeArray, null, count($arr)); + $res->depth = $depth; + $items = &$res->items; + $arr = array_slice($arr, 0, $this->maxItems, preserve_keys: true); + } + + $items = []; + foreach ($arr as $k => $v) { + $refId = $this->getReferenceId($arr, $k); + $items[] = [ + $this->describeVar($k, $depth + 1), + $this->isSensitive((string) $k, $v) + ? new Value(Value::TypeText, self::hideValue($v)) + : $this->describeVar($v, $depth + 1, $refId), + ] + ($refId ? [2 => $refId] : []); + } + + return $res ?? $items; + } + + + private function describeObject(object $obj, int $depth = 0): Value + { + $id = spl_object_id($obj); + $value = &$this->snapshot[$id]; + if ($value && $value->depth <= $depth) { + return new Value(Value::TypeRef, $id); + } + + $value = new Value(Value::TypeObject, get_debug_type($obj)); + $value->id = $id; + $value->depth = $depth; + $value->holder = $obj; // to be not released by garbage collector in collecting mode + if ($this->location) { + $rc = $obj instanceof \Closure + ? new \ReflectionFunction($obj) + : new \ReflectionClass($obj); + if ($rc->getFileName() && ($editor = Helpers::editorUri($rc->getFileName(), $rc->getStartLine()))) { + $value->editor = (object) ['file' => $rc->getFileName(), 'line' => $rc->getStartLine(), 'url' => $editor]; + } + } + + if ($this->maxDepth && $depth < $this->maxDepth) { + $value->items = []; + $props = $this->exposeObject($obj, $value); + foreach ($props ?? [] as $k => $v) { + $this->addPropertyTo($value, (string) $k, $v, Value::PropertyVirtual, $this->getReferenceId($props, $k)); + } + } + + return new Value(Value::TypeRef, $id); + } + + + /** + * @param resource $resource + */ + private function describeResource($resource, int $depth = 0): Value + { + $id = 'r' . (int) $resource; + $value = &$this->snapshot[$id]; + if (!$value) { + $type = is_resource($resource) ? get_resource_type($resource) : 'closed'; + $value = new Value(Value::TypeResource, $type . ' resource'); + $value->id = $id; + $value->depth = $depth; + $value->items = []; + if (isset($this->resourceExposers[$type])) { + foreach (($this->resourceExposers[$type])($resource) as $k => $v) { + $value->items[] = [htmlspecialchars($k), $this->describeVar($v, $depth + 1)]; + } + } + } + + return new Value(Value::TypeRef, $id); + } + + + public function describeKey(string $key): Value|string + { + if (preg_match('#^[\w!\#$%&*+./;<>?@^{|}~-]{1,50}$#D', $key) && !preg_match('#^(true|false|null)$#iD', $key)) { + return $key; + } + + $value = $this->describeString($key); + return is_string($value) // ensure result is Value + ? new Value(Value::TypeStringHtml, $key, Helpers::utf8Length($key)) + : $value; + } + + + public function addPropertyTo( + Value $value, + string $k, + mixed $v, + int $type = Value::PropertyVirtual, + ?int $refId = null, + ?string $class = null, + ?Value $described = null, + ): void + { + if ($value->depth && $this->maxItems && count($value->items ?? []) >= $this->maxItems) { + $value->length = ($value->length ?? count($value->items)) + 1; + return; + } + + $class ??= $value->value; + $value->items[] = [ + $this->describeKey($k), + $type !== Value::PropertyVirtual && $this->isSensitive($k, $v, $class) + ? new Value(Value::TypeText, self::hideValue($v)) + : ($described ?? $this->describeVar($v, $value->depth + 1, $refId)), + $type === Value::PropertyPrivate ? $class : $type, + ] + ($refId ? [3 => $refId] : []); + } + + + private function exposeObject(object $obj, Value $value): ?array + { + foreach ($this->objectExposers as $type => $dumper) { + if (!$type || $obj instanceof $type) { + return $dumper($obj, $value, $this); + } + } + + if ($this->debugInfo && method_exists($obj, '__debugInfo')) { + return $obj->__debugInfo(); + } + + Exposer::exposeObject($obj, $value, $this); + return null; + } + + + private function isSensitive(string $key, mixed $val, ?string $class = null): bool + { + return $val instanceof \SensitiveParameterValue + || ($this->scrubber !== null && ($this->scrubber)($key, $val, $class)) + || isset($this->keysToHide[strtolower($key)]) + || isset($this->keysToHide[strtolower($class . '::$' . $key)]); + } + + + private static function hideValue(mixed $val): string + { + if ($val instanceof \SensitiveParameterValue) { + $val = $val->getValue(); + } + + return self::HiddenValue . ' (' . get_debug_type($val) . ')'; + } + + + public function describeEnumProperty(string $class, string $property, mixed $value): ?Value + { + [$set, $constants] = $this->enumProperties["$class::$property"] ?? null; + if (!is_int($value) + || !$constants + || !($constants = Helpers::decomposeFlags($value, $set, $constants)) + ) { + return null; + } + + $constants = array_map(fn(string $const): string => str_replace("$class::", 'self::', $const), $constants); + return new Value(Value::TypeNumber, implode(' | ', $constants) . " ($value)"); + } + + + public function getReferenceId(array $arr, string|int $key): ?int + { + return ($rr = \ReflectionReference::fromArrayElement($arr, $key)) + ? ($this->references[$rr->getId()] ??= count($this->references) + 1) + : null; + } + + + /** + * Finds the location where dump was called. Returns [file, line, code] + */ + private static function findLocation(): ?array + { + foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $item) { + if (isset($item['class']) && ($item['class'] === self::class || $item['class'] === Tracy\Dumper::class)) { + $location = $item; + continue; + } elseif (isset($item['function'])) { + try { + $reflection = isset($item['class']) + ? new \ReflectionMethod($item['class'], $item['function']) + : new \ReflectionFunction($item['function']); + if ( + $reflection->isInternal() + || preg_match('#\s@tracySkipLocation\s#', (string) $reflection->getDocComment()) + ) { + $location = $item; + continue; + } + } catch (\ReflectionException) { + } + } + + break; + } + + if (isset($location['file'], $location['line']) && @is_file($location['file'])) { // @ - may trigger error + $lines = file($location['file']); + $line = $lines[$location['line'] - 1]; + return [ + $location['file'], + $location['line'], + trim(preg_match('#\w*dump(er::\w+)?\(.*\)#i', $line, $m) ? $m[0] : $line), + ]; + } + + return null; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php b/vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php new file mode 100644 index 0000000..ca7938f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Dumper.php @@ -0,0 +1,262 @@ + '1;33', + 'null' => '1;33', + 'number' => '1;32', + 'string' => '1;36', + 'array' => '1;31', + 'public' => '1;37', + 'protected' => '1;37', + 'private' => '1;37', + 'dynamic' => '1;37', + 'virtual' => '1;37', + 'object' => '1;31', + 'resource' => '1;37', + 'indent' => '1;30', + ]; + + public static array $resources = [ + 'stream' => 'stream_get_meta_data', + 'stream-context' => 'stream_context_get_options', + 'curl' => 'curl_getinfo', + ]; + + public static array $objectExporters = [ + \Closure::class => [Exposer::class, 'exposeClosure'], + \UnitEnum::class => [Exposer::class, 'exposeEnum'], + \ArrayObject::class => [Exposer::class, 'exposeArrayObject'], + \SplFileInfo::class => [Exposer::class, 'exposeSplFileInfo'], + \SplObjectStorage::class => [Exposer::class, 'exposeSplObjectStorage'], + \__PHP_Incomplete_Class::class => [Exposer::class, 'exposePhpIncompleteClass'], + \Generator::class => [Exposer::class, 'exposeGenerator'], + \Fiber::class => [Exposer::class, 'exposeFiber'], + \DOMNode::class => [Exposer::class, 'exposeDOMNode'], + \DOMNodeList::class => [Exposer::class, 'exposeDOMNodeList'], + \DOMNamedNodeMap::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\Node::class => [Exposer::class, 'exposeDOMNode'], + Dom\NodeList::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\NamedNodeMap::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\TokenList::class => [Exposer::class, 'exposeDOMNodeList'], + Dom\HTMLCollection::class => [Exposer::class, 'exposeDOMNodeList'], + Ds\Collection::class => [Exposer::class, 'exposeDsCollection'], + Ds\Map::class => [Exposer::class, 'exposeDsMap'], + \WeakMap::class => [Exposer::class, 'exposeWeakMap'], + ]; + + /** @var array */ + private static array $enumProperties = []; + + private Describer $describer; + private Renderer $renderer; + + + /** + * Dumps variable to the output. + */ + public static function dump(mixed $var, array $options = []): mixed + { + if (Helpers::isCli()) { + $useColors = self::$terminalColors && Helpers::detectColors(); + $dumper = new self($options); + fwrite(STDOUT, $dumper->asTerminal($var, $useColors ? self::$terminalColors : [])); + + } elseif (Helpers::isHtmlMode()) { + $options[self::LOCATION] ??= true; + self::renderAssets(); + echo self::toHtml($var, $options); + + } else { + echo self::toText($var, $options); + } + + return $var; + } + + + /** + * Dumps variable to HTML. + */ + public static function toHtml(mixed $var, array $options = [], mixed $key = null): string + { + return (new self($options))->asHtml($var, $key); + } + + + /** + * Dumps variable to plain text. + */ + public static function toText(mixed $var, array $options = []): string + { + return (new self($options))->asTerminal($var); + } + + + /** + * Dumps variable to x-terminal. + */ + public static function toTerminal(mixed $var, array $options = []): string + { + return (new self($options))->asTerminal($var, self::$terminalColors); + } + + + /** + * Renders \n"; + } + } + + + private function __construct(array $options = []) + { + $location = $options[self::LOCATION] ?? 0; + $location = $location === true ? ~0 : (int) $location; + + $describer = $this->describer = new Describer; + $describer->maxDepth = (int) ($options[self::DEPTH] ?? $describer->maxDepth); + $describer->maxLength = (int) ($options[self::TRUNCATE] ?? $describer->maxLength); + $describer->maxItems = (int) ($options[self::ITEMS] ?? $describer->maxItems); + $describer->debugInfo = (bool) ($options[self::DEBUGINFO] ?? $describer->debugInfo); + $describer->scrubber = $options[self::SCRUBBER] ?? $describer->scrubber; + $describer->keysToHide = array_flip(array_map('strtolower', $options[self::KEYS_TO_HIDE] ?? [])); + $describer->resourceExposers = ($options['resourceExporters'] ?? []) + self::$resources; + $describer->objectExposers = ($options[self::OBJECT_EXPORTERS] ?? []) + self::$objectExporters; + $describer->enumProperties = self::$enumProperties; + $describer->location = (bool) $location; + if ($options[self::LIVE] ?? false) { + $tmp = &self::$liveSnapshot; + } elseif (isset($options[self::SNAPSHOT])) { + $tmp = &$options[self::SNAPSHOT]; + } + + if (isset($tmp)) { + $tmp[0] ??= []; + $tmp[1] ??= []; + $describer->snapshot = &$tmp[0]; + $describer->references = &$tmp[1]; + } + + $renderer = $this->renderer = new Renderer; + $renderer->collapseTop = $options[self::COLLAPSE] ?? $renderer->collapseTop; + $renderer->collapseSub = $options[self::COLLAPSE_COUNT] ?? $renderer->collapseSub; + $renderer->collectingMode = isset($options[self::SNAPSHOT]) || !empty($options[self::LIVE]); + $renderer->lazy = $renderer->collectingMode + ? true + : ($options[self::LAZY] ?? $renderer->lazy); + $renderer->sourceLocation = !(~$location & self::LOCATION_SOURCE); + $renderer->classLocation = !(~$location & self::LOCATION_CLASS); + $renderer->theme = ($options[self::THEME] ?? $renderer->theme) ?: null; + $renderer->hash = $options[self::HASH] ?? true; + } + + + /** + * Dumps variable to HTML. + */ + private function asHtml(mixed $var, mixed $key = null): string + { + if ($key === null) { + $model = $this->describer->describe($var); + } else { + $model = $this->describer->describe([$key => $var]); + $model->value = $model->value[0][1]; + } + + return $this->renderer->renderAsHtml($model); + } + + + /** + * Dumps variable to x-terminal. + */ + private function asTerminal(mixed $var, array $colors = []): string + { + $model = $this->describer->describe($var); + return $this->renderer->renderAsText($model, $colors); + } + + + public static function formatSnapshotAttribute(array &$snapshot): string + { + $res = "'" . Renderer::jsonEncode($snapshot[0] ?? []) . "'"; + $snapshot = []; + return $res; + } + + + public static function addEnumProperty(string $class, string $property, array $constants, bool $set = false): void + { + self::$enumProperties["$class::$property"] = [$set, $constants]; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php b/vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php new file mode 100644 index 0000000..773f541 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Exposer.php @@ -0,0 +1,279 @@ + $v) { + $describer->addPropertyTo($value, (string) $k, $v); + } + + foreach (array_diff_key($values, $props) as $k => $v) { + $describer->addPropertyTo( + $value, + (string) $k, + $v, + Value::PropertyDynamic, + $describer->getReferenceId($values, $k), + ); + } + + foreach ($props as $k => [$name, $class, $type]) { + if (array_key_exists($k, $values)) { + $describer->addPropertyTo( + $value, + $name, + $values[$k], + $type, + $describer->getReferenceId($values, $k), + $class, + $describer->describeEnumProperty($class, $name, $values[$k]), + ); + } else { + $describer->addPropertyTo( + $value, + $name, + null, + $type, + class: $class, + described: new Value(Value::TypeText, 'unset'), + ); + } + } + } + + + private static function getProperties(string $class): array + { + static $cache; + if (isset($cache[$class])) { + return $cache[$class]; + } + + $rc = new \ReflectionClass($class); + $parentProps = $rc->getParentClass() ? self::getProperties($rc->getParentClass()->getName()) : []; + $props = []; + + foreach ($rc->getProperties() as $prop) { + $name = $prop->getName(); + if ($prop->isStatic() || $prop->getDeclaringClass()->getName() !== $class) { + // nothing + } elseif ($prop->isPrivate()) { + $props["\x00" . $class . "\x00" . $name] = [$name, $class, Value::PropertyPrivate]; + } elseif ($prop->isProtected()) { + $props["\x00*\x00" . $name] = [$name, $class, Value::PropertyProtected]; + } else { + $props[$name] = [$name, $class, Value::PropertyPublic]; + unset($parentProps["\x00*\x00" . $name]); + } + } + + return $cache[$class] = $props + $parentProps; + } + + + public static function exposeClosure(\Closure $obj, Value $value, Describer $describer): void + { + $rc = new \ReflectionFunction($obj); + if ($describer->location) { + $describer->addPropertyTo($value, 'file', $rc->getFileName() . ':' . $rc->getStartLine()); + } + + $params = []; + foreach ($rc->getParameters() as $param) { + $params[] = '$' . $param->getName(); + } + + $value->value .= '(' . implode(', ', $params) . ')'; + + $uses = []; + $useValue = new Value(Value::TypeObject); + $useValue->depth = $value->depth + 1; + foreach ($rc->getStaticVariables() as $name => $v) { + $uses[] = '$' . $name; + $describer->addPropertyTo($useValue, '$' . $name, $v); + } + + if ($uses) { + $useValue->value = implode(', ', $uses); + $useValue->collapsed = true; + $describer->addPropertyTo($value, 'use', null, described: $useValue); + } + } + + + public static function exposeEnum(\UnitEnum $enum, Value $value, Describer $describer): void + { + $value->value = $enum::class . '::' . $enum->name; + if ($enum instanceof \BackedEnum) { + $describer->addPropertyTo($value, 'value', $enum->value); + $value->collapsed = true; + } + } + + + public static function exposeArrayObject(\ArrayObject $obj, Value $value, Describer $describer): void + { + $flags = $obj->getFlags(); + $obj->setFlags(\ArrayObject::STD_PROP_LIST); + self::exposeObject($obj, $value, $describer); + $obj->setFlags($flags); + $describer->addPropertyTo($value, 'storage', $obj->getArrayCopy(), Value::PropertyPrivate, null, \ArrayObject::class); + $value->value .= ' (' . count($obj) . ')'; + } + + + public static function exposeDOMNode(\DOMNode|Dom\Node $obj, Value $value, Describer $describer): void + { + $props = preg_match_all('#^\s*\[([^\]]+)\] =>#m', print_r($obj, return: true), $tmp) ? $tmp[1] : []; + sort($props); + foreach ($props as $p) { + $describer->addPropertyTo($value, $p, @$obj->$p, Value::PropertyPublic); // @ some props may be deprecated + } + } + + + public static function exposeDOMNodeList( + \DOMNodeList|\DOMNamedNodeMap|Dom\NodeList|Dom\NamedNodeMap|Dom\TokenList|Dom\HTMLCollection $obj, + Value $value, + Describer $describer, + ): void + { + $describer->addPropertyTo($value, 'length', $obj->length, Value::PropertyPublic); + $describer->addPropertyTo($value, 'items', iterator_to_array($obj)); + } + + + public static function exposeGenerator(\Generator $gen, Value $value, Describer $describer): void + { + try { + $r = new \ReflectionGenerator($gen); + $describer->addPropertyTo($value, 'file', $r->getExecutingFile() . ':' . $r->getExecutingLine()); + $describer->addPropertyTo($value, 'this', $r->getThis()); + } catch (\ReflectionException) { + $value->value = $gen::class . ' (terminated)'; + } + } + + + public static function exposeFiber(\Fiber $fiber, Value $value, Describer $describer): void + { + if ($fiber->isTerminated()) { + $value->value = $fiber::class . ' (terminated)'; + } elseif (!$fiber->isStarted()) { + $value->value = $fiber::class . ' (not started)'; + } else { + $r = new \ReflectionFiber($fiber); + $describer->addPropertyTo($value, 'file', $r->getExecutingFile() . ':' . $r->getExecutingLine()); + $describer->addPropertyTo($value, 'callable', $r->getCallable()); + } + } + + + public static function exposeSplFileInfo(\SplFileInfo $obj): array + { + return ['path' => $obj->getPathname()]; + } + + + public static function exposeSplObjectStorage(\SplObjectStorage $obj, Value $value, Describer $describer): void + { + $value->value .= ' (' . count($obj) . ')'; + foreach (clone $obj as $v) { + $pair = new Value(Value::TypeObject, ''); + $pair->depth = $value->depth + 1; + $describer->addPropertyTo($pair, 'key', $v); + $describer->addPropertyTo($pair, 'value', $obj[$v]); + $describer->addPropertyTo($value, '', null, described: $pair); + $value->items[array_key_last($value->items)][0] = ''; + } + } + + + public static function exposeWeakMap(\WeakMap $obj, Value $value, Describer $describer): void + { + $value->value .= ' (' . count($obj) . ')'; + foreach ($obj as $k => $v) { + $pair = new Value(Value::TypeObject, ''); + $pair->depth = $value->depth + 1; + $describer->addPropertyTo($pair, 'key', $k); + $describer->addPropertyTo($pair, 'value', $v); + $describer->addPropertyTo($value, '', null, described: $pair); + $value->items[array_key_last($value->items)][0] = ''; + } + } + + + public static function exposePhpIncompleteClass( + \__PHP_Incomplete_Class $obj, + Value $value, + Describer $describer, + ): void + { + $values = get_mangled_object_vars($obj); + $class = $values['__PHP_Incomplete_Class_Name']; + unset($values['__PHP_Incomplete_Class_Name']); + foreach ($values as $k => $v) { + $refId = $describer->getReferenceId($values, $k); + if (isset($k[0]) && $k[0] === "\x00") { + $info = explode("\00", $k); + $k = end($info); + $type = $info[1] === '*' ? Value::PropertyProtected : Value::PropertyPrivate; + $decl = $type === Value::PropertyPrivate ? $info[1] : null; + } else { + $type = Value::PropertyPublic; + $k = (string) $k; + $decl = null; + } + + $describer->addPropertyTo($value, $k, $v, $type, $refId, $decl); + } + + $value->value = $class . ' (Incomplete Class)'; + } + + + public static function exposeDsCollection( + Ds\Collection $obj, + Value $value, + Describer $describer, + ): void + { + foreach (clone $obj as $k => $v) { + $describer->addPropertyTo($value, (string) $k, $v); + } + } + + + public static function exposeDsMap( + Ds\Map $obj, + Value $value, + Describer $describer, + ): void + { + $i = 0; + foreach ($obj as $k => $v) { + $describer->addPropertyTo($value, (string) $i++, new Ds\Pair($k, $v)); + } + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php b/vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php new file mode 100644 index 0000000..5d9c9ec --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Renderer.php @@ -0,0 +1,426 @@ +value; + $this->snapshot = $model->snapshot; + + if ($this->lazy === false) { // no lazy-loading + $html = $this->renderVar($value); + $json = $snapshot = null; + + } elseif ($this->lazy && (is_array($value) && $value || is_object($value))) { // full lazy-loading + $html = ''; + $snapshot = $this->collectingMode ? null : $this->snapshot; + $json = $value; + + } else { // lazy-loading of collapsed parts + $html = $this->renderVar($value); + $snapshot = $this->snapshotSelection; + $json = null; + } + } finally { + $this->parents = $this->snapshot = $this->above = []; + $this->snapshotSelection = null; + } + + $location = null; + if ($model->location && $this->sourceLocation) { + [$file, $line, $code] = $model->location; + $uri = Helpers::editorUri($file, $line); + $location = Helpers::formatHtml( + '', + $uri ?? '#', + $file, + $line, + $uri ? "\nClick to open in editor" : '', + ) . Helpers::encodeString($code, 50) . " 📍"; + } + + return '
 100 ? "\n" : '')
+			. '>'
+			. $location
+			. $html
+			. "
\n"; + } + + + public function renderAsText(\stdClass $model, array $colors = []): string + { + try { + $this->snapshot = $model->snapshot; + $this->lazy = false; + $s = $this->renderVar($model->value); + } finally { + $this->parents = $this->snapshot = $this->above = []; + } + + $s = $colors ? Helpers::htmlToAnsi($s, $colors) : Helpers::htmlToText($s); + $s = str_replace('…', '...', $s); + $s .= substr($s, -1) === "\n" ? '' : "\n"; + + if ($this->sourceLocation && ([$file, $line] = $model->location)) { + $s .= "in $file:$line\n"; + } + + return $s; + } + + + private function renderVar(mixed $value, int $depth = 0, string|int|null $keyType = null): string + { + return match (true) { + $value === null => 'null', + is_bool($value) => '' . ($value ? 'true' : 'false') . '', + is_int($value) => '' . $value . '', + is_float($value) => '' . self::jsonEncode($value) . '', + is_string($value) => $this->renderString($value, $depth, $keyType), + is_array($value), $value->type === Value::TypeArray => $this->renderArray($value, $depth), + $value->type === Value::TypeRef => $this->renderVar($this->snapshot[$value->value], $depth, $keyType), + $value->type === Value::TypeObject => $this->renderObject($value, $depth), + $value->type === Value::TypeNumber => '' . Helpers::escapeHtml($value->value) . '', + $value->type === Value::TypeText => '' . Helpers::escapeHtml($value->value) . '', + $value->type === Value::TypeStringHtml, $value->type === Value::TypeBinaryHtml => $this->renderString($value, $depth, $keyType), + $value->type === Value::TypeResource => $this->renderResource($value, $depth), + default => throw new \Exception('Unknown type'), + }; + } + + + private function renderString(string|Value $str, int $depth, string|int|null $keyType): string + { + if ($keyType === self::TypeArrayKey) { + $indent = ' ' . str_repeat('| ', $depth - 1) . ' '; + return '' + . "'" + . (is_string($str) ? Helpers::escapeHtml($str) : str_replace("\n", "\n" . $indent, $str->value)) + . "'" + . ''; + + } elseif ($keyType !== null) { + $classes = [ + Value::PropertyPublic => 'tracy-dump-public', + Value::PropertyProtected => 'tracy-dump-protected', + Value::PropertyDynamic => 'tracy-dump-dynamic', + Value::PropertyVirtual => 'tracy-dump-virtual', + ]; + $indent = ' ' . str_repeat('| ', $depth - 1) . ' '; + $title = is_string($keyType) + ? ' title="declared in ' . Helpers::escapeHtml($keyType) . '"' + : null; + return '' + . (is_string($str) + ? Helpers::escapeHtml($str) + : "'" . str_replace("\n", "\n" . $indent, $str->value) . "'") + . ''; + + } elseif (is_string($str)) { + $len = Helpers::utf8Length($str); + return ' 1 ? ' title="' . $len . ' characters"' : '') + . '>' + . "'" + . Helpers::escapeHtml($str) + . "'" + . ''; + + } else { + $unit = $str->type === Value::TypeStringHtml ? 'characters' : 'bytes'; + $count = substr_count($str->value, "\n"); + if ($count) { + $collapsed = $indent1 = $toggle = null; + $indent = ' '; + if ($depth) { + $collapsed = $count >= $this->collapseSub; + $indent1 = ' ' . str_repeat('| ', $depth) . ''; + $indent = ' ' . str_repeat('| ', $depth) . ' '; + $toggle = 'string' . "\n"; + } + + return $toggle + . '
' + . $indent1 + . ''" + . str_replace("\n", "\n" . $indent, $str->value) + . "'" + . ($depth ? "\n" : '') + . '
'; + } + + return 'length > 1 ? " title=\"{$str->length} $unit\"" : '') + . '>' + . "'" + . $str->value + . "'" + . ''; + } + } + + + private function renderArray(array|Value $array, int $depth): string + { + $out = 'array ('; + + if (is_array($array)) { + $items = $array; + $count = count($items); + $out .= $count . ')'; + } elseif ($array->items === null) { + return $out . $array->length . ') …'; + } else { + $items = $array->items; + $count = $array->length ?? count($items); + $out .= $count . ')'; + if ($array->id && isset($this->parents[$array->id])) { + return $out . ' RECURSION'; + + } elseif ($array->id && ($array->depth < $depth || isset($this->above[$array->id]))) { + if ($this->lazy !== false) { + $ref = new Value(Value::TypeRef, $array->id); + $this->copySnapshot($ref); + return '" . $out . ''; + + } elseif ($this->hash) { + return $out . (isset($this->above[$array->id]) ? ' see above' : ' see below'); + } + } + } + + if (!$count) { + return $out; + } + + $collapsed = $depth + ? ($this->lazy === false || $depth === 1 ? $count >= $this->collapseSub : true) + : (is_int($this->collapseTop) ? $count >= $this->collapseTop : $this->collapseTop); + + $span = 'lazy !== false) { + $array = isset($array->id) ? new Value(Value::TypeRef, $array->id) : $array; + $this->copySnapshot($array); + return $span . " data-tracy-dump='" . self::jsonEncode($array) . "'>" . $out . ''; + } + + $out = $span . '>' . $out . "\n" . ''; + $indent = ' ' . str_repeat('| ', $depth) . ''; + $this->parents[$array->id ?? ''] = $this->above[$array->id ?? ''] = true; + + foreach ($items as $info) { + [$k, $v, $ref] = $info + [2 => null]; + $out .= $indent + . $this->renderVar($k, $depth + 1, self::TypeArrayKey) + . ' => ' + . ($ref && $this->hash ? '&' . $ref . ' ' : '') + . ($tmp = $this->renderVar($v, $depth + 1)) + . (substr($tmp, -6) === '' ? '' : "\n"); + } + + if ($count > count($items)) { + $out .= $indent . "…\n"; + } + + unset($this->parents[$array->id ?? '']); + return $out . ''; + } + + + private function renderObject(Value $object, int $depth): string + { + $editorAttributes = ''; + if ($this->classLocation && $object->editor) { + $editorAttributes = Helpers::formatHtml( + ' title="Declared in file % on line %%%" data-tracy-href="%"', + $object->editor->file, + $object->editor->line, + $object->editor->url ? "\nCtrl-Click to open in editor" : '', + "\nAlt-Click to expand/collapse all child nodes", + $object->editor->url, + ); + } + + $pos = strrpos($object->value, '\\'); + $out = '' + . ($pos + ? Helpers::escapeHtml(substr($object->value, 0, $pos + 1)) . '' . Helpers::escapeHtml(substr($object->value, $pos + 1)) . '' + : Helpers::escapeHtml($object->value)) + . '' + . ($object->id && $this->hash ? ' #' . $object->id . '' : ''); + + if ($object->items === null) { + return $out . ' …'; + + } elseif (!$object->items) { + return $out; + + } elseif ($object->id && isset($this->parents[$object->id])) { + return $out . ' RECURSION'; + + } elseif ($object->id && ($object->depth < $depth || isset($this->above[$object->id]))) { + if ($this->lazy !== false) { + $ref = new Value(Value::TypeRef, $object->id); + $this->copySnapshot($ref); + return '" . $out . ''; + + } elseif ($this->hash) { + return $out . (isset($this->above[$object->id]) ? ' see above' : ' see below'); + } + } + + $collapsed = $object->collapsed ?? ($depth + ? ($this->lazy === false || $depth === 1 ? count($object->items) >= $this->collapseSub : true) + : (is_int($this->collapseTop) ? count($object->items) >= $this->collapseTop : $this->collapseTop)); + + $span = 'lazy !== false) { + $value = $object->id ? new Value(Value::TypeRef, $object->id) : $object; + $this->copySnapshot($value); + return $span . " data-tracy-dump='" . self::jsonEncode($value) . "'>" . $out . ''; + } + + $out = $span . '>' . $out . "\n" . ''; + $indent = ' ' . str_repeat('| ', $depth) . ''; + $this->parents[$object->id ?? ''] = $this->above[$object->id ?? ''] = true; + + foreach ($object->items as $info) { + [$k, $v, $type, $ref] = $info + [2 => Value::PropertyVirtual, null]; + $out .= $indent + . $this->renderVar($k, $depth + 1, $type) + . ': ' + . ($ref && $this->hash ? '&' . $ref . ' ' : '') + . ($tmp = $this->renderVar($v, $depth + 1)) + . (substr($tmp, -6) === '' ? '' : "\n"); + } + + if ($object->length > count($object->items)) { + $out .= $indent . "…\n"; + } + + unset($this->parents[$object->id ?? '']); + return $out . ''; + } + + + private function renderResource(Value $resource, int $depth): string + { + $out = '' . Helpers::escapeHtml($resource->value) . ' ' + . ($this->hash ? '@' . substr($resource->id, 1) . '' : ''); + + if (!$resource->items) { + return $out; + + } elseif (isset($this->above[$resource->id])) { + if ($this->lazy !== false) { + $ref = new Value(Value::TypeRef, $resource->id); + $this->copySnapshot($ref); + return '" . $out . ''; + } + + return $out . ' see above'; + + } else { + $this->above[$resource->id] = true; + $out = "$out\n
"; + foreach ($resource->items as [$k, $v]) { + $out .= ' ' . str_repeat('| ', $depth) . '' + . $this->renderVar($k, $depth + 1, Value::PropertyVirtual) + . ': ' + . ($tmp = $this->renderVar($v, $depth + 1)) + . (substr($tmp, -6) === '
' ? '' : "\n"); + } + + return $out . ''; + } + } + + + private function copySnapshot(mixed $value): void + { + if ($this->collectingMode) { + return; + } + + if ($this->snapshotSelection === null) { + $this->snapshotSelection = []; + } + + if (is_array($value)) { + foreach ($value as [, $v]) { + $this->copySnapshot($v); + } + } elseif ($value instanceof Value && $value->type === Value::TypeRef) { + if (!isset($this->snapshotSelection[$value->value])) { + $ref = $this->snapshotSelection[$value->value] = $this->snapshot[$value->value]; + $this->copySnapshot($ref); + } + } elseif ($value instanceof Value && $value->items) { + foreach ($value->items as [, $v]) { + $this->copySnapshot($v); + } + } + } + + + public static function jsonEncode(mixed $value): string + { + $old = @ini_set('serialize_precision', '-1'); // @ may be disabled + try { + return json_encode($value, JSON_HEX_APOS | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } finally { + if ($old !== false) { + ini_set('serialize_precision', $old); + } + } + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/Value.php b/vendor/tracy/tracy/src/Tracy/Dumper/Value.php new file mode 100644 index 0000000..5fa6e44 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/Value.php @@ -0,0 +1,65 @@ +type = $type; + $this->value = $value; + $this->length = $length; + } + + + public function jsonSerialize(): array + { + $res = [$this->type => $this->value]; + foreach (['length', 'editor', 'items', 'collapsed'] as $k) { + if ($this->$k !== null) { + $res[$k] = $this->$k; + } + } + + return $res; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css new file mode 100644 index 0000000..8346d72 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-dark.css @@ -0,0 +1,145 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-dump.tracy-dark { + text-align: left; + color: #f8f8f2; + background: #29292e; + border-radius: 4px; + padding: var(--tracy-space); + margin: var(--tracy-space) 0; + word-break: break-all; + white-space: pre-wrap; +} + +.tracy-dump.tracy-dark div { + padding-left: 2.5ex; +} + +.tracy-dump.tracy-dark div div { + border-left: 1px solid rgba(255, 255, 255, .1); + margin-left: .5ex; +} + +.tracy-dump.tracy-dark div div:hover { + border-left-color: rgba(255, 255, 255, .25); +} + +.tracy-dark .tracy-dump-location { + color: silver; + font-size: 80%; + text-decoration: none; + background: none; + opacity: .5; + float: right; + cursor: pointer; +} + +.tracy-dark .tracy-dump-location:hover, +.tracy-dark .tracy-dump-location:focus { + opacity: 1; +} + +.tracy-dark .tracy-dump-array, +.tracy-dark .tracy-dump-object { + color: #f69c2e; + user-select: text; +} + +.tracy-dark .tracy-dump-string { + color: #3cdfef; + white-space: break-spaces; +} + +.tracy-dark div.tracy-dump-string { + position: relative; + padding-left: 3.5ex; +} + +.tracy-dark .tracy-dump-lq { + margin-left: calc(-1ex - 1px); +} + +.tracy-dark div.tracy-dump-string:before { + content: ''; + position: absolute; + left: calc(3ex - 1px); + top: 1.5em; + bottom: 0; + border-left: 1px solid rgba(255, 255, 255, .1); +} + +.tracy-dark .tracy-dump-virtual span, +.tracy-dark .tracy-dump-dynamic span, +.tracy-dark .tracy-dump-string span { + color: rgba(255, 255, 255, 0.5); +} + +.tracy-dark .tracy-dump-virtual i, +.tracy-dark .tracy-dump-dynamic i, +.tracy-dark .tracy-dump-string i { + font-size: 80%; + font-style: normal; + color: rgba(255, 255, 255, 0.5); + user-select: none; +} + +.tracy-dark .tracy-dump-number { + color: #77d285; +} + +.tracy-dark .tracy-dump-null, +.tracy-dark .tracy-dump-bool { + color: #f3cb44; +} + +.tracy-dark .tracy-dump-virtual { + font-style: italic; +} + +.tracy-dark .tracy-dump-public::after { + content: ' pub'; +} + +.tracy-dark .tracy-dump-protected::after { + content: ' pro'; +} + +.tracy-dark .tracy-dump-private::after { + content: ' pri'; +} + +.tracy-dark .tracy-dump-public::after, +.tracy-dark .tracy-dump-protected::after, +.tracy-dark .tracy-dump-private::after, +.tracy-dark .tracy-dump-hash { + font-size: 85%; + color: rgba(255, 255, 255, 0.35); +} + +.tracy-dark .tracy-dump-indent { + display: none; +} + +.tracy-dark .tracy-dump-highlight { + background: #C22; + color: white; + border-radius: 2px; + padding: 0 2px; + margin: 0 -2px; +} + +span[data-tracy-href] { + border-bottom: 1px dotted rgba(255, 255, 255, .2); +} + +.tracy-dark .tracy-dump-flash { + animation: tracy-dump-flash .2s ease; +} + +@keyframes tracy-dump-flash { + 0% { + background: #c0c0c033; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css new file mode 100644 index 0000000..fb86592 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper-light.css @@ -0,0 +1,145 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-dump.tracy-light { + text-align: left; + color: #444; + background: #fdf9e2; + border-radius: 4px; + padding: var(--tracy-space); + margin: var(--tracy-space) 0; + word-break: break-all; + white-space: pre-wrap; +} + +.tracy-dump.tracy-light div { + padding-left: 2.5ex; +} + +.tracy-dump.tracy-light div div { + border-left: 1px solid rgba(0, 0, 0, .1); + margin-left: .5ex; +} + +.tracy-dump.tracy-light div div:hover { + border-left-color: rgba(0, 0, 0, .25); +} + +.tracy-light .tracy-dump-location { + color: gray; + font-size: 80%; + text-decoration: none; + background: none; + opacity: .5; + float: right; + cursor: pointer; +} + +.tracy-light .tracy-dump-location:hover, +.tracy-light .tracy-dump-location:focus { + opacity: 1; +} + +.tracy-light .tracy-dump-array, +.tracy-light .tracy-dump-object { + color: #C22; + user-select: text; +} + +.tracy-light .tracy-dump-string { + color: #35D; + white-space: break-spaces; +} + +.tracy-light div.tracy-dump-string { + position: relative; + padding-left: 3.5ex; +} + +.tracy-light .tracy-dump-lq { + margin-left: calc(-1ex - 1px); +} + +.tracy-light div.tracy-dump-string:before { + content: ''; + position: absolute; + left: calc(3ex - 1px); + top: 1.5em; + bottom: 0; + border-left: 1px solid rgba(0, 0, 0, .1); +} + +.tracy-light .tracy-dump-virtual span, +.tracy-light .tracy-dump-dynamic span, +.tracy-light .tracy-dump-string span { + color: rgba(0, 0, 0, 0.5); +} + +.tracy-light .tracy-dump-virtual i, +.tracy-light .tracy-dump-dynamic i, +.tracy-light .tracy-dump-string i { + font-size: 80%; + font-style: normal; + color: rgba(0, 0, 0, 0.5); + user-select: none; +} + +.tracy-light .tracy-dump-number { + color: #090; +} + +.tracy-light .tracy-dump-null, +.tracy-light .tracy-dump-bool { + color: #850; +} + +.tracy-light .tracy-dump-virtual { + font-style: italic; +} + +.tracy-light .tracy-dump-public::after { + content: ' pub'; +} + +.tracy-light .tracy-dump-protected::after { + content: ' pro'; +} + +.tracy-light .tracy-dump-private::after { + content: ' pri'; +} + +.tracy-light .tracy-dump-public::after, +.tracy-light .tracy-dump-protected::after, +.tracy-light .tracy-dump-private::after, +.tracy-light .tracy-dump-hash { + font-size: 85%; + color: rgba(0, 0, 0, 0.35); +} + +.tracy-light .tracy-dump-indent { + display: none; +} + +.tracy-light .tracy-dump-highlight { + background: #C22; + color: white; + border-radius: 2px; + padding: 0 2px; + margin: 0 -2px; +} + +span[data-tracy-href] { + border-bottom: 1px dotted rgba(0, 0, 0, .2); +} + +.tracy-light .tracy-dump-flash { + animation: tracy-dump-flash .2s ease; +} + +@keyframes tracy-dump-flash { + 0% { + background: #c0c0c033; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js new file mode 100644 index 0000000..81417ad --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Dumper/assets/dumper.js @@ -0,0 +1,392 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +const + COLLAPSE_COUNT = 7, + COLLAPSE_COUNT_TOP = 14, + TYPE_ARRAY = 'a', + TYPE_OBJECT = 'o', + TYPE_RESOURCE = 'r', + PROP_VIRTUAL = 4, + PROP_PRIVATE = 2; + +const + HINT_CTRL = 'Ctrl-Click to open in editor', + HINT_ALT = 'Alt-Click to expand/collapse all child nodes'; + +class Dumper { + static init(context) { + // full lazy + (context || document).querySelectorAll('[data-tracy-snapshot][data-tracy-dump]').forEach((pre) => { //
+			let snapshot = JSON.parse(pre.getAttribute('data-tracy-snapshot'));
+			pre.removeAttribute('data-tracy-snapshot');
+			pre.appendChild(build(JSON.parse(pre.getAttribute('data-tracy-dump')), snapshot, pre.classList.contains('tracy-collapsed')));
+			pre.removeAttribute('data-tracy-dump');
+			pre.classList.remove('tracy-collapsed');
+		});
+
+		// snapshots
+		(context || document).querySelectorAll('meta[itemprop=tracy-snapshot]').forEach((meta) => {
+			let snapshot = JSON.parse(meta.getAttribute('content'));
+			meta.parentElement.querySelectorAll('[data-tracy-dump]').forEach((pre) => { // 
+				if (pre.closest('[data-tracy-snapshot]')) { // ignore unrelated 
+					return;
+				}
+				pre.appendChild(build(JSON.parse(pre.getAttribute('data-tracy-dump')), snapshot, pre.classList.contains('tracy-collapsed')));
+				pre.removeAttribute('data-tracy-dump');
+				pre.classList.remove('tracy-collapsed');
+			});
+			//  must be left for debug bar panel content
+		});
+
+		if (Dumper.inited) {
+			return;
+		}
+		Dumper.inited = true;
+
+		document.documentElement.addEventListener('click', (e) => {
+			let el;
+			// enables  & ctrl or cmd key
+			if ((e.ctrlKey || e.metaKey) && (el = e.target.closest('[data-tracy-href]'))) {
+				location.href = el.getAttribute('data-tracy-href');
+				return false;
+			}
+
+		});
+
+		document.documentElement.addEventListener('tracy-beforetoggle', (e) => {
+			let el;
+			// initializes lazy  inside 
+			if ((el = e.target.closest('[data-tracy-snapshot]'))) {
+				let snapshot = JSON.parse(el.getAttribute('data-tracy-snapshot'));
+				el.removeAttribute('data-tracy-snapshot');
+				el.querySelectorAll('[data-tracy-dump]').forEach((toggler) => {
+					if (!toggler.nextSibling) {
+						toggler.after(document.createTextNode('\n')); // enforce \n after toggler
+					}
+					toggler.nextSibling.after(buildStruct(JSON.parse(toggler.getAttribute('data-tracy-dump')), snapshot, toggler, true, []));
+					toggler.removeAttribute('data-tracy-dump');
+				});
+			}
+		});
+
+		document.documentElement.addEventListener('tracy-toggle', (e) => {
+			if (!e.target.matches('.tracy-dump *')) {
+				return;
+			}
+
+			let cont = e.detail.relatedTarget;
+			let origE = e.detail.originalEvent;
+
+			if (origE && origE.usedIds) { // triggered by expandChild()
+				toggleChildren(cont, origE.usedIds);
+				return;
+
+			} else if (origE && origE.altKey && cont.querySelector('.tracy-toggle')) { // triggered by alt key
+				if (e.detail.collapsed) { // reopen
+					e.target.classList.toggle('tracy-collapsed', false);
+					cont.classList.toggle('tracy-collapsed', false);
+					e.detail.collapsed = false;
+				}
+
+				let expand = e.target.tracyAltExpand = !e.target.tracyAltExpand;
+				toggleChildren(cont, expand ? {} : false);
+			}
+
+			cont.classList.toggle('tracy-dump-flash', !e.detail.collapsed);
+		});
+
+		document.documentElement.addEventListener('animationend', (e) => {
+			if (e.animationName === 'tracy-dump-flash') {
+				e.target.classList.toggle('tracy-dump-flash', false);
+			}
+		});
+
+		document.addEventListener('mouseover', (e) => {
+			if (!e.target.matches('.tracy-dump *')) {
+				return;
+			}
+
+			let el;
+
+			if (e.target.matches('.tracy-dump-hash') && (el = e.target.closest('tracy-div'))) {
+				el.querySelectorAll('.tracy-dump-hash').forEach((el) => {
+					if (el.textContent === e.target.textContent) {
+						el.classList.add('tracy-dump-highlight');
+					}
+				});
+				return;
+			}
+
+			if ((el = e.target.closest('.tracy-toggle')) && !el.title) {
+				el.title = HINT_ALT;
+			}
+		});
+
+		document.addEventListener('mouseout', (e) => {
+			if (e.target.matches('.tracy-dump-hash')) {
+				document.querySelectorAll('.tracy-dump-hash.tracy-dump-highlight').forEach((el) => {
+					el.classList.remove('tracy-dump-highlight');
+				});
+			}
+		});
+
+		Tracy.Toggle.init();
+	}
+}
+
+
+function build(data, repository, collapsed, parentIds, keyType) {
+	let id, type = data === null ? 'null' : typeof data,
+		collapseCount = collapsed === null ? COLLAPSE_COUNT : COLLAPSE_COUNT_TOP;
+
+	if (type === 'null' || type === 'number' || type === 'boolean') {
+		return createEl(null, null, [
+			createEl(
+				'span',
+				{ class: 'tracy-dump-' + type.replace('ean', '') },
+				[data + ''],
+			),
+		]);
+
+	} else if (type === 'string') {
+		data = {
+			string: data.replace(/&/g, '&').replace(/\'' + s + '\'' },
+				),
+			]);
+
+		} else if (keyType !== undefined) {
+			if (type !== 'string') {
+				s = '\'' + s + '\'';
+			}
+
+			const classes = [
+				'tracy-dump-public',
+				'tracy-dump-protected',
+				'tracy-dump-private',
+				'tracy-dump-dynamic',
+				'tracy-dump-virtual',
+			];
+			return createEl(null, null, [
+				createEl(
+					'span',
+					{
+						class: classes[typeof keyType === 'string' ? PROP_PRIVATE : keyType],
+						title: typeof keyType === 'string' ? 'declared in ' + keyType : null,
+					},
+					{ html: s },
+				),
+			]);
+		}
+
+		let count = (s.match(/\n/g) || []).length;
+		if (count) {
+			let collapsed = count >= COLLAPSE_COUNT;
+			return createEl(null, null, [
+				createEl('span', { class: collapsed ? 'tracy-toggle tracy-collapsed' : 'tracy-toggle' }, ['string']),
+				'\n',
+				createEl(
+					'div',
+					{
+						class: 'tracy-dump-string' + (collapsed ? ' tracy-collapsed' : ''),
+						title: data.length + (data.bin ? ' bytes' : ' characters'),
+					},
+					{ html: '\'' + s + '\'' },
+				),
+			]);
+		}
+
+		return createEl(null, null, [
+			createEl(
+				'span',
+				{
+					class: 'tracy-dump-string',
+					title: data.length + (data.bin ? ' bytes' : ' characters'),
+				},
+				{ html: '\'' + s + '\'' },
+			),
+		]);
+
+	} else if (data.number) {
+		return createEl(null, null, [
+			createEl('span', { class: 'tracy-dump-number' }, [data.number]),
+		]);
+
+	} else if (data.text !== undefined) {
+		return createEl(null, null, [
+			createEl('span', { class: 'tracy-dump-virtual' }, [data.text]),
+		]);
+
+	} else { // object || resource || array
+		let pos, nameEl;
+		nameEl = data.object && (pos = data.object.lastIndexOf('\\')) > 0
+			? [data.object.substr(0, pos + 1), createEl('b', null, [data.object.substr(pos + 1)])]
+			: [data.object || data.resource];
+
+		let span = data.array !== undefined
+			? [
+					createEl('span', { class: 'tracy-dump-array' }, ['array']),
+					' (' + (data.length || data.items.length) + ')',
+				]
+			: [
+					createEl('span', {
+						'class': data.object ? 'tracy-dump-object' : 'tracy-dump-resource',
+						'title': data.editor ? 'Declared in file ' + data.editor.file + ' on line ' + data.editor.line + (data.editor.url ? '\n' + HINT_CTRL : '') + '\n' + HINT_ALT : null,
+						'data-tracy-href': data.editor ? data.editor.url : null,
+					}, nameEl),
+					...(id ? [' ', createEl('span', { class: 'tracy-dump-hash' }, [data.resource ? '@' + id.substr(1) : '#' + id])] : []),
+				];
+
+		parentIds = parentIds ? parentIds.slice() : [];
+		let recursive = id && parentIds.indexOf(id) > -1;
+		parentIds.push(id);
+
+		if (recursive || !data.items || !data.items.length) {
+			span.push(recursive ? ' RECURSION' : (!data.items || data.items.length ? ' …' : ''));
+			return createEl(null, null, span);
+		}
+
+		collapsed = collapsed === true || data.collapsed || (data.items && data.items.length >= collapseCount);
+		let toggle = createEl('span', { class: collapsed ? 'tracy-toggle tracy-collapsed' : 'tracy-toggle' }, span);
+
+		return createEl(null, null, [
+			toggle,
+			'\n',
+			buildStruct(data, repository, toggle, collapsed, parentIds),
+		]);
+	}
+}
+
+
+function buildStruct(data, repository, toggle, collapsed, parentIds) {
+	if (Array.isArray(data)) {
+		data = { items: data };
+
+	} else if (data.ref) {
+		parentIds = parentIds.slice();
+		parentIds.push(data.ref);
+		data = repository[data.ref];
+	}
+
+	let cut = data.items && data.length > data.items.length;
+	let type = data.object ? TYPE_OBJECT : data.resource ? TYPE_RESOURCE : TYPE_ARRAY;
+	let div = createEl('div', { class: collapsed ? 'tracy-collapsed' : null });
+
+	if (collapsed) {
+		let handler;
+		toggle.addEventListener('tracy-toggle', handler = function () {
+			toggle.removeEventListener('tracy-toggle', handler);
+			createItems(div, data.items, type, repository, parentIds, null);
+			if (cut) {
+				createEl(div, null, ['…\n']);
+			}
+		});
+	} else {
+		createItems(div, data.items, type, repository, parentIds, true);
+		if (cut) {
+			createEl(div, null, ['…\n']);
+		}
+	}
+
+	return div;
+}
+
+
+function createEl(el, attrs, content) {
+	if (!(el instanceof Node)) {
+		el = el ? document.createElement(el) : document.createDocumentFragment();
+	}
+	for (let id in attrs || {}) {
+		if (attrs[id] !== null) {
+			el.setAttribute(id, attrs[id]);
+		}
+	}
+
+	if (content && content.html !== undefined) {
+		el.innerHTML = content.html;
+		return el;
+	}
+
+	content = content || [];
+	el.append(...content.filter((child) => (child !== null)));
+	return el;
+}
+
+
+function createItems(el, items, type, repository, parentIds, collapsed) {
+	let key, val, vis, ref, i, tmp;
+
+	for (i = 0; i < items.length; i++) {
+		if (type === TYPE_ARRAY) {
+			[key, val, ref] = items[i];
+		} else {
+			[key, val, vis = PROP_VIRTUAL, ref] = items[i];
+		}
+
+		createEl(el, null, [
+			build(key, null, null, null, type === TYPE_ARRAY ? TYPE_ARRAY : vis),
+			type === TYPE_ARRAY ? ' => ' : ': ',
+			...(ref ? [createEl('span', { class: 'tracy-dump-hash' }, ['&' + ref]), ' '] : []),
+			tmp = build(val, repository, collapsed, parentIds),
+			tmp.lastElementChild.tagName === 'DIV' ? '' : '\n',
+		]);
+	}
+}
+
+
+function toggleChildren(cont, usedIds) {
+	let hashEl, id;
+
+	cont.querySelectorAll(':scope > .tracy-toggle').forEach((el) => {
+		hashEl = (el.querySelector('.tracy-dump-hash') || el.previousElementSibling);
+		id = hashEl && hashEl.matches('.tracy-dump-hash') ? hashEl.textContent : null;
+
+		if (!usedIds || (id && usedIds[id])) {
+			Tracy.Toggle.toggle(el, false);
+		} else {
+			usedIds[id] = true;
+			Tracy.Toggle.toggle(el, true, { usedIds: usedIds });
+		}
+	});
+}
+
+
+function UnknownEntityException() {}
+
+
+let Tracy = window.Tracy = window.Tracy || {};
+Tracy.Dumper = Tracy.Dumper || Dumper;
+
+function init() {
+	Tracy.Dumper.init();
+}
+
+if (document.readyState === 'loading') {
+	document.addEventListener('DOMContentLoaded', init);
+} else {
+	init();
+}
diff --git a/vendor/tracy/tracy/src/Tracy/Helpers.php b/vendor/tracy/tracy/src/Tracy/Helpers.php
new file mode 100644
index 0000000..8264fb6
--- /dev/null
+++ b/vendor/tracy/tracy/src/Tracy/Helpers.php
@@ -0,0 +1,648 @@
+%%%',
+				$editor,
+				$origFile . ($line ? ":$line" : ''),
+				rtrim(dirname($file), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR,
+				basename($file),
+				$line ? ":$line" : '',
+			);
+		} else {
+			return self::formatHtml('%', $file . ($line ? ":$line" : ''));
+		}
+	}
+
+
+	/**
+	 * Returns link to editor.
+	 */
+	public static function editorUri(
+		string $file,
+		?int $line = null,
+		string $action = 'open',
+		string $search = '',
+		string $replace = '',
+	): ?string
+	{
+		if (Debugger::$editor && $file && ($action === 'create' || @is_file($file))) { // @ - may trigger error
+			$file = strtr($file, '/', DIRECTORY_SEPARATOR);
+			$file = strtr($file, Debugger::$editorMapping);
+			$search = str_replace("\n", PHP_EOL, $search);
+			$replace = str_replace("\n", PHP_EOL, $replace);
+			return strtr(Debugger::$editor, [
+				'%action' => $action,
+				'%file' => rawurlencode($file),
+				'%line' => $line ?: 1,
+				'%search' => rawurlencode($search),
+				'%replace' => rawurlencode($replace),
+			]);
+		}
+
+		return null;
+	}
+
+
+	public static function formatHtml(string $mask): string
+	{
+		$args = func_get_args();
+		return preg_replace_callback('#%#', function () use (&$args, &$count): string {
+			return str_replace("\n", '
', self::escapeHtml($args[++$count]));
+		}, $mask);
+	}
+
+
+	public static function escapeHtml(mixed $s): string
+	{
+		return htmlspecialchars((string) $s, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
+	}
+
+
+	public static function htmlToText(string $s): string
+	{
+		return htmlspecialchars_decode(strip_tags($s), ENT_QUOTES | ENT_HTML5);
+	}
+
+
+	public static function findTrace(array $trace, array|string $method, ?int &$index = null): ?array
+	{
+		$m = is_array($method) ? $method : explode('::', $method);
+		foreach ($trace as $i => $item) {
+			if (
+				isset($item['function'])
+				&& $item['function'] === end($m)
+				&& isset($item['class']) === isset($m[1])
+				&& (!isset($item['class']) || $m[0] === '*' || is_a($item['class'], $m[0], allow_string: true))
+			) {
+				$index = $i;
+				return $item;
+			}
+		}
+
+		return null;
+	}
+
+
+	/** @internal */
+	public static function errorTypeToString(int $type): string
+	{
+		$types = [
+			E_ERROR => 'Fatal Error',
+			E_USER_ERROR => 'User Error',
+			E_RECOVERABLE_ERROR => 'Recoverable Error',
+			E_CORE_ERROR => 'Core Error',
+			E_COMPILE_ERROR => 'Compile Error',
+			E_PARSE => 'Parse Error',
+			E_WARNING => 'Warning',
+			E_CORE_WARNING => 'Core Warning',
+			E_COMPILE_WARNING => 'Compile Warning',
+			E_USER_WARNING => 'User Warning',
+			E_NOTICE => 'Notice',
+			E_USER_NOTICE => 'User Notice',
+			E_DEPRECATED => 'Deprecated',
+			E_USER_DEPRECATED => 'User Deprecated',
+		];
+		return $types[$type] ?? 'Unknown error';
+	}
+
+
+	/** @internal */
+	public static function getSource(): string
+	{
+		if (self::isCli()) {
+			return 'CLI (PID: ' . getmypid() . ')'
+				. (isset($_SERVER['argv']) ? ': ' . implode(' ', array_map([self::class, 'escapeArg'], $_SERVER['argv'])) : '');
+
+		} elseif (isset($_SERVER['REQUEST_URI'])) {
+			return (!empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off') ? 'https://' : 'http://')
+				. ($_SERVER['HTTP_HOST'] ?? '')
+				. $_SERVER['REQUEST_URI'];
+
+		} else {
+			return PHP_SAPI;
+		}
+	}
+
+
+	/** @internal */
+	public static function improveException(\Throwable $e): void
+	{
+		$message = $e->getMessage();
+		if (
+			!($e instanceof \Error || $e instanceof \ErrorException)
+			|| str_contains($e->getMessage(), 'did you mean')
+		) {
+			// do nothing
+		} elseif (preg_match('~Argument #(\d+)(?: \(\$\w+\))? must be of type callable, (.+ given)~', $message, $m)) {
+			$arg = $e->getTrace()[0]['args'][$m[1] - 1] ?? null;
+			if (is_string($arg) && str_contains($arg, '::')) {
+				$arg = explode('::', $arg, 2);
+			}
+			if (!is_callable($arg, syntax_only: true)) {
+				// do nothing
+			} elseif (is_array($arg) && is_string($arg[0]) && !class_exists($arg[0]) && !trait_exists($arg[0])) {
+				$message = str_replace($m[2], "but class '$arg[0]' does not exist", $message);
+			} elseif (is_array($arg) && !method_exists($arg[0], $arg[1])) {
+				$hint = self::getSuggestion(get_class_methods($arg[0]) ?: [], $arg[1]);
+				$class = is_object($arg[0]) ? get_class($arg[0]) : $arg[0];
+				$message = str_replace($m[2], "but method $class::$arg[1]() does not exist" . ($hint ? " (did you mean $hint?)" : ''), $message);
+			} elseif (is_string($arg) && !function_exists($arg)) {
+				$funcs = array_merge(get_defined_functions()['internal'], get_defined_functions()['user']);
+				$hint = self::getSuggestion($funcs, $arg);
+				$message = str_replace($m[2], "but function '$arg' does not exist" . ($hint ? " (did you mean $hint?)" : ''), $message);
+			}
+
+		} elseif (preg_match('#^Call to undefined function (\S+\\\)?(\w+)\(#', $message, $m)) {
+			$funcs = array_merge(get_defined_functions()['internal'], get_defined_functions()['user']);
+			if ($hint = self::getSuggestion($funcs, $m[1] . $m[2]) ?: self::getSuggestion($funcs, $m[2])) {
+				$message = "Call to undefined function $m[2](), did you mean $hint()?";
+				$replace = ["$m[2](", "$hint("];
+			}
+
+		} elseif (preg_match('#^Call to undefined method ([\w\\\]+)::(\w+)#', $message, $m)) {
+			if ($hint = self::getSuggestion(get_class_methods($m[1]) ?: [], $m[2])) {
+				$message .= ", did you mean $hint()?";
+				$replace = ["$m[2](", "$hint("];
+			}
+
+		} elseif (preg_match('#^Undefined property: ([\w\\\]+)::\$(\w+)#', $message, $m)) {
+			$rc = new \ReflectionClass($m[1]);
+			$items = array_filter($rc->getProperties(\ReflectionProperty::IS_PUBLIC), fn($prop) => !$prop->isStatic());
+			if ($hint = self::getSuggestion($items, $m[2])) {
+				$message .= ", did you mean $$hint?";
+				$replace = ["->$m[2]", "->$hint"];
+			}
+
+		} elseif (preg_match('#^Access to undeclared static property:? ([\w\\\]+)::\$(\w+)#', $message, $m)) {
+			$rc = new \ReflectionClass($m[1]);
+			$items = array_filter($rc->getProperties(\ReflectionProperty::IS_STATIC), fn($prop) => $prop->isPublic());
+			if ($hint = self::getSuggestion($items, $m[2])) {
+				$message .= ", did you mean $$hint?";
+				$replace = ["::$$m[2]", "::$$hint"];
+			}
+		}
+
+		if ($message !== $e->getMessage()) {
+			$ref = new \ReflectionProperty($e, 'message');
+			$ref->setValue($e, $message);
+		}
+
+		if (isset($replace)) {
+			$loc = Debugger::mapSource($e->getFile(), $e->getLine()) ?? ['file' => $e->getFile(), 'line' => $e->getLine()];
+			@$e->tracyAction = [ // dynamic properties are deprecated since PHP 8.2
+				'link' => self::editorUri($loc['file'], $loc['line'], 'fix', $replace[0], $replace[1]),
+				'label' => 'fix it',
+			];
+		}
+	}
+
+
+	/** @internal */
+	public static function improveError(string $message): string
+	{
+		if (preg_match('#^Undefined property: ([\w\\\]+)::\$(\w+)#', $message, $m)) {
+			$rc = new \ReflectionClass($m[1]);
+			$items = array_filter($rc->getProperties(\ReflectionProperty::IS_PUBLIC), fn($prop) => !$prop->isStatic());
+			$hint = self::getSuggestion($items, $m[2]);
+			return $hint ? $message . ", did you mean $$hint?" : $message;
+		}
+
+		return $message;
+	}
+
+
+	/** @internal */
+	public static function guessClassFile(string $class): ?string
+	{
+		$segments = explode('\\', $class);
+		$res = null;
+		$max = 0;
+		foreach (get_declared_classes() as $class) {
+			$parts = explode('\\', $class);
+			foreach ($parts as $i => $part) {
+				if ($part !== ($segments[$i] ?? null)) {
+					break;
+				}
+			}
+
+			if ($i > $max && $i < count($segments) && ($file = (new \ReflectionClass($class))->getFileName())) {
+				$max = $i;
+				$res = array_merge(array_slice(explode(DIRECTORY_SEPARATOR, $file), 0, $i - count($parts)), array_slice($segments, $i));
+				$res = implode(DIRECTORY_SEPARATOR, $res) . '.php';
+			}
+		}
+
+		return $res;
+	}
+
+
+	/**
+	 * Finds the best suggestion.
+	 * @internal
+	 */
+	public static function getSuggestion(array $items, string $value): ?string
+	{
+		$best = null;
+		$min = (strlen($value) / 4 + 1) * 10 + .1;
+		$items = array_map(fn($item) => $item instanceof \Reflector ? $item->getName() : (string) $item, $items);
+		foreach (array_unique($items) as $item) {
+			if (($len = levenshtein($item, $value, 10, 11, 10)) > 0 && $len < $min) {
+				$min = $len;
+				$best = $item;
+			}
+		}
+
+		return $best;
+	}
+
+
+	/** @internal */
+	public static function isHtmlMode(): bool
+	{
+		return empty($_SERVER['HTTP_X_REQUESTED_WITH'])
+			&& empty($_SERVER['HTTP_X_TRACY_AJAX'])
+			&& isset($_SERVER['HTTP_HOST'])
+			&& !self::isCli()
+			&& !preg_match('#^Content-Type: *+(?!text/html)#im', implode("\n", headers_list()));
+	}
+
+
+	/** @internal */
+	public static function isAjax(): bool
+	{
+		return isset($_SERVER['HTTP_X_TRACY_AJAX']) && preg_match('#^\w{10,15}$#D', $_SERVER['HTTP_X_TRACY_AJAX']);
+	}
+
+
+	/** @internal */
+	public static function isRedirect(): bool
+	{
+		return (bool) preg_match('#^Location:#im', implode("\n", headers_list()));
+	}
+
+
+	/** @internal */
+	public static function createId(): string
+	{
+		return bin2hex(random_bytes(5));
+	}
+
+
+	/** @internal */
+	public static function isCli(): bool
+	{
+		return PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg';
+	}
+
+
+	/** @internal */
+	public static function getNonceAttr(): string
+	{
+		return preg_match('#^Content-Security-Policy(?:-Report-Only)?:.*\sscript-src\s+(?:[^;]+\s)?\'nonce-([\w+/]+=*)\'#mi', implode("\n", headers_list()), $m)
+			? ' nonce="' . self::escapeHtml($m[1]) . '"'
+			: '';
+	}
+
+
+	/**
+	 * Escape a string to be used as a shell argument.
+	 */
+	private static function escapeArg(string $s): string
+	{
+		if (preg_match('#^[a-z0-9._=/:-]+$#Di', $s)) {
+			return $s;
+		}
+
+		return defined('PHP_WINDOWS_VERSION_BUILD')
+			? '"' . str_replace('"', '""', $s) . '"'
+			: escapeshellarg($s);
+	}
+
+
+	/**
+	 * Captures PHP output into a string.
+	 */
+	public static function capture(callable $func): string
+	{
+		ob_start(fn() => '');
+		try {
+			$func();
+			return ob_get_clean();
+		} catch (\Throwable $e) {
+			ob_end_clean();
+			throw $e;
+		}
+	}
+
+
+	/** @internal */
+	public static function encodeString(string $s, ?int $maxLength = null, bool $showWhitespaces = true): string
+	{
+		$utf8 = self::isUtf8($s);
+		$len = $utf8 ? self::utf8Length($s) : strlen($s);
+		return $maxLength && $len > $maxLength + 20
+			? self::doEncodeString(self::truncateString($s, $maxLength, $utf8), $utf8, $showWhitespaces)
+				. '  '
+				. self::doEncodeString(self::truncateString($s, -10, $utf8), $utf8, $showWhitespaces)
+			: self::doEncodeString($s, $utf8, $showWhitespaces);
+	}
+
+
+	private static function doEncodeString(string $s, bool $utf8, bool $showWhitespaces): string
+	{
+		$specials = [
+			true => [
+				"\r" => '\r',
+				"\n" => "\\n\n",
+				"\t" => '\t    ',
+				"\e" => '\e',
+				'<' => '<',
+				'&' => '&',
+			],
+			false => [
+				"\r" => "\r",
+				"\n" => "\n",
+				"\t" => "\t",
+				"\e" => '\e',
+				'<' => '<',
+				'&' => '&',
+			],
+		];
+		$special = $specials[$showWhitespaces];
+		$s = preg_replace_callback(
+			$utf8 ? '#[\p{C}<&]#u' : '#[\x00-\x1F\x7F-\xFF<&]#',
+			fn($m) => $special[$m[0]] ?? (strlen($m[0]) === 1
+					? '\x' . str_pad(strtoupper(dechex(ord($m[0]))), 2, '0', STR_PAD_LEFT) . ''
+					: '\u{' . strtoupper(ltrim(dechex(self::utf8Ord($m[0])), '0')) . '}'),
+			$s,
+		);
+		$s = str_replace('', '', $s);
+		$s = preg_replace('~\n$~D', '', $s);
+		return $s;
+	}
+
+
+	private static function utf8Ord(string $c): int
+	{
+		$ord0 = ord($c[0]);
+		if ($ord0 < 0x80) {
+			return $ord0;
+		} elseif ($ord0 < 0xE0) {
+			return ($ord0 << 6) + ord($c[1]) - 0x3080;
+		} elseif ($ord0 < 0xF0) {
+			return ($ord0 << 12) + (ord($c[1]) << 6) + ord($c[2]) - 0xE2080;
+		} else {
+			return ($ord0 << 18) + (ord($c[1]) << 12) + (ord($c[2]) << 6) + ord($c[3]) - 0x3C82080;
+		}
+	}
+
+
+	/** @internal */
+	public static function utf8Length(string $s): int
+	{
+		return match (true) {
+			extension_loaded('mbstring') => mb_strlen($s, 'UTF-8'),
+			extension_loaded('iconv') => iconv_strlen($s, 'UTF-8'),
+			default => strlen(@utf8_decode($s)), // deprecated
+		};
+	}
+
+
+	/** @internal */
+	public static function isUtf8(string $s): bool
+	{
+		return (bool) preg_match('##u', $s);
+	}
+
+
+	/** @internal */
+	public static function truncateString(string $s, int $len, bool $utf8): string
+	{
+		if (!$utf8) {
+			return $len < 0 ? substr($s, $len) : substr($s, 0, $len);
+		} elseif (function_exists('mb_substr')) {
+			return $len < 0
+				? mb_substr($s, $len, -$len, 'UTF-8')
+				: mb_substr($s, 0, $len, 'UTF-8');
+		} else {
+			$len < 0
+				? preg_match('#.{0,' . -$len . '}\z#us', $s, $m)
+				: preg_match("#^.{0,$len}#us", $s, $m);
+			return $m[0];
+		}
+	}
+
+
+	/** @internal */
+	public static function htmlToAnsi(string $s, array $colors): string
+	{
+		$stack = ['0'];
+		$s = preg_replace_callback(
+			'#<\w+(?: class=["\']tracy-(?:dump-)?([\w-]+)["\'])?[^>]*>|#',
+			function ($m) use ($colors, &$stack): string {
+				if ($m[0][1] === '/') {
+					array_pop($stack);
+				} else {
+					$stack[] = isset($m[1], $colors[$m[1]]) ? $colors[$m[1]] : '0';
+				}
+				return "\e[" . end($stack) . 'm';
+			},
+			$s,
+		);
+		$s = preg_replace('/\e\[0m( *)(?=\e)/', '$1', $s);
+		$s = self::htmlToText($s);
+		return $s;
+	}
+
+
+	/** @internal */
+	public static function minifyJs(string $s): string
+	{
+		// author: Jakub Vrana https://php.vrana.cz/minifikace-javascriptu.php
+		$last = '';
+		return preg_replace_callback(
+			<<<'XX'
+				(
+					(?:
+						(^|[-+\([{}=,:;!%^&*|?~]|/(?![/*])|return|throw) # context before regexp
+						(?:\s|//[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+						(/(?![/*])(?:\\[^\n]|[^[\n/\\]|\[(?:\\[^\n]|[^]])++)+/) # regexp
+						|(^
+							|'(?:\\.|[^\n'\\])*'
+							|"(?:\\.|[^\n"\\])*"
+							|([0-9A-Za-z_$]+)
+							|([-+]+)
+							|.
+						)
+					)(?:\s|//[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+				())sx
+				XX,
+			function ($match) use (&$last) {
+				[, $context, $regexp, $result, $word, $operator] = $match;
+				if ($word !== '') {
+					$result = ($last === 'word' ? ' ' : ($last === 'return' ? ' ' : '')) . $result;
+					$last = ($word === 'return' || $word === 'throw' || $word === 'break' ? 'return' : 'word');
+				} elseif ($operator) {
+					$result = ($last === $operator[0] ? ' ' : '') . $result;
+					$last = $operator[0];
+				} else {
+					if ($regexp) {
+						$result = $context . ($context === '/' ? ' ' : '') . $regexp;
+					}
+
+					$last = '';
+				}
+
+				return $result;
+			},
+			$s . "\n",
+		);
+	}
+
+
+	/** @internal */
+	public static function minifyCss(string $s): string
+	{
+		$last = '';
+		return preg_replace_callback(
+			<<<'XX'
+				(
+					(^
+						|'(?:\\.|[^\n'\\])*'
+						|"(?:\\.|[^\n"\\])*"
+						|([0-9A-Za-z_*#.%:()[\]-]+)
+						|.
+					)(?:\s|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+				())sx
+				XX,
+			function ($match) use (&$last) {
+				[, $result, $word] = $match;
+				if ($last === ';') {
+					$result = $result === '}' ? '}' : ';' . $result;
+					$last = '';
+				}
+
+				if ($word !== '') {
+					$result = ($last === 'word' ? ' ' : '') . $result;
+					$last = 'word';
+				} elseif ($result === ';') {
+					$last = ';';
+					$result = '';
+				} else {
+					$last = '';
+				}
+
+				return $result;
+			},
+			$s . "\n",
+		);
+	}
+
+
+	public static function detectColors(): bool
+	{
+		return self::isCli()
+			&& getenv('NO_COLOR') === false // https://no-color.org
+			&& (getenv('FORCE_COLOR')
+				|| (function_exists('sapi_windows_vt100_support')
+					? sapi_windows_vt100_support(STDOUT)
+					: @stream_isatty(STDOUT)) // @ may trigger error 'cannot cast a filtered stream on this system'
+			);
+	}
+
+
+	public static function getExceptionChain(\Throwable $ex): array
+	{
+		$res = [$ex];
+		while (($ex = $ex->getPrevious()) && !in_array($ex, $res, true)) {
+			$res[] = $ex;
+		}
+
+		return $res;
+	}
+
+
+	public static function traverseValue(mixed $val, callable $callback, array &$skip = [], ?string $refId = null): void
+	{
+		if (is_object($val)) {
+			$id = spl_object_id($val);
+			if (!isset($skip[$id])) {
+				$skip[$id] = true;
+				$callback($val);
+				self::traverseValue((array) $val, $callback, $skip);
+			}
+
+		} elseif (is_array($val)) {
+			if ($refId) {
+				if (isset($skip[$refId])) {
+					return;
+				}
+				$skip[$refId] = true;
+			}
+
+			foreach ($val as $k => $v) {
+				$refId = \ReflectionReference::fromArrayElement($val, $k)?->getId();
+				self::traverseValue($v, $callback, $skip, $refId);
+			}
+		}
+	}
+
+
+	/** @internal */
+	public static function decomposeFlags(int $flags, bool $set, array $constants): ?array
+	{
+		$res = null;
+		foreach ($constants as $constant) {
+			if (defined($constant)) {
+				$v = constant($constant);
+				if ($set) {
+					if ($v && ($flags & $v) === $v) {
+						$res[] = $constant;
+						$flags &= ~$v;
+					}
+				} elseif ($flags === $v) {
+					return [$constant];
+				}
+			}
+		}
+
+		if ($flags && $res && $set) {
+			$res[] = (string) $flags;
+		}
+		return $res;
+	}
+}
diff --git a/vendor/tracy/tracy/src/Tracy/Logger/ILogger.php b/vendor/tracy/tracy/src/Tracy/Logger/ILogger.php
new file mode 100644
index 0000000..de32dab
--- /dev/null
+++ b/vendor/tracy/tracy/src/Tracy/Logger/ILogger.php
@@ -0,0 +1,27 @@
+directory = $directory;
+		$this->email = $email;
+		$this->blueScreen = $blueScreen;
+		$this->mailer = [$this, 'defaultMailer'];
+	}
+
+
+	/**
+	 * Logs message or exception to file and sends email notification.
+	 * For levels ERROR, EXCEPTION and CRITICAL it sends email.
+	 * @return string|null logged error filename
+	 */
+	public function log(mixed $message, string $level = self::INFO)
+	{
+		if (!$this->directory) {
+			throw new \LogicException('Logging directory is not specified.');
+		} elseif (!is_dir($this->directory)) {
+			throw new \RuntimeException("Logging directory '$this->directory' is not found or is not directory.");
+		}
+
+		$exceptionFile = $message instanceof \Throwable
+			? $this->getExceptionFile($message, $level)
+			: null;
+		$line = static::formatLogLine($message, $exceptionFile);
+		$file = $this->directory . '/' . strtolower($level ?: self::INFO) . '.log';
+
+		if (!@file_put_contents($file, $line . PHP_EOL, FILE_APPEND | LOCK_EX)) { // @ is escalated to exception
+			throw new \RuntimeException("Unable to write to log file '$file'. Is directory writable?");
+		}
+
+		if ($exceptionFile) {
+			$this->logException($message, $exceptionFile);
+		}
+
+		if (in_array($level, [self::ERROR, self::EXCEPTION, self::CRITICAL], true)) {
+			$this->sendEmail($message);
+		}
+
+		return $exceptionFile;
+	}
+
+
+	/**
+	 * @param  mixed  $message
+	 */
+	public static function formatMessage($message): string
+	{
+		if ($message instanceof \Throwable) {
+			foreach (Helpers::getExceptionChain($message) as $exception) {
+				$tmp[] = ($exception instanceof \ErrorException
+					? Helpers::errorTypeToString($exception->getSeverity()) . ': ' . $exception->getMessage()
+					: get_debug_type($exception) . ': ' . $exception->getMessage() . ($exception->getCode() ? ' #' . $exception->getCode() : '')
+				) . ' in ' . $exception->getFile() . ':' . $exception->getLine();
+			}
+
+			$message = implode("\ncaused by ", $tmp);
+
+		} elseif (!is_string($message)) {
+			$message = Dumper::toText($message);
+		}
+
+		return trim($message);
+	}
+
+
+	/**
+	 * @param  mixed  $message
+	 */
+	public static function formatLogLine($message, ?string $exceptionFile = null): string
+	{
+		return implode(' ', [
+			date('[Y-m-d H-i-s]'),
+			preg_replace('#\s*\r?\n\s*#', ' ', static::formatMessage($message)),
+			' @  ' . Helpers::getSource(),
+			$exceptionFile ? ' @@  ' . basename($exceptionFile) : null,
+		]);
+	}
+
+
+	public function getExceptionFile(\Throwable $exception, string $level = self::EXCEPTION): string
+	{
+		foreach (Helpers::getExceptionChain($exception) as $exception) {
+			$data[] = [
+				$exception::class, $exception->getMessage(), $exception->getCode(), $exception->getFile(), $exception->getLine(),
+				array_map(function (array $item): array {
+					unset($item['args']);
+					return $item;
+				}, $exception->getTrace()),
+			];
+		}
+
+		$hash = substr(hash('xxh128', serialize($data)), 0, 10);
+		$dir = strtr($this->directory . '/', '\/', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);
+		foreach (new \DirectoryIterator($this->directory) as $file) {
+			if (strpos($file->getBasename(), $hash)) {
+				return $dir . $file;
+			}
+		}
+
+		return $dir . $level . '--' . date('Y-m-d--H-i') . "--$hash.html";
+	}
+
+
+	/**
+	 * Logs exception to the file if file doesn't exist.
+	 * @return string logged error filename
+	 */
+	protected function logException(\Throwable $exception, ?string $file = null): string
+	{
+		$file = $file ?: $this->getExceptionFile($exception);
+		$bs = $this->blueScreen ?: new BlueScreen;
+		$bs->renderToFile($exception, $file);
+		return $file;
+	}
+
+
+	/**
+	 * @param  mixed  $message
+	 */
+	protected function sendEmail($message): void
+	{
+		$snooze = is_numeric($this->emailSnooze)
+			? $this->emailSnooze
+			: strtotime($this->emailSnooze) - time();
+
+		if (
+			$this->email
+			&& $this->mailer
+			&& @filemtime($this->directory . '/email-sent') + $snooze < time() // @ file may not exist
+			&& @file_put_contents($this->directory . '/email-sent', 'sent') // @ file may not be writable
+		) {
+			($this->mailer)($message, implode(', ', (array) $this->email));
+		}
+	}
+
+
+	/**
+	 * Default mailer.
+	 * @param  mixed  $message
+	 * @internal
+	 */
+	public function defaultMailer($message, string $email): void
+	{
+		$host = preg_replace('#[^\w.-]+#', '', $_SERVER['SERVER_NAME'] ?? php_uname('n'));
+		mail(
+			$email,
+			"PHP: An error occurred on the server $host",
+			static::formatMessage($message) . "\n\nsource: " . Helpers::getSource(),
+			implode("\r\n", [
+				'From: ' . ($this->fromEmail ?: "noreply@$host"),
+				'X-Mailer: Tracy',
+				'Content-Type: text/plain; charset=UTF-8',
+				'Content-Transfer-Encoding: 8bit',
+			]),
+		);
+	}
+}
diff --git a/vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php b/vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php
new file mode 100644
index 0000000..fe95590
--- /dev/null
+++ b/vendor/tracy/tracy/src/Tracy/OutputDebugger/OutputDebugger.php
@@ -0,0 +1,86 @@
+start();
+	}
+
+
+	public function start(): void
+	{
+		foreach (get_included_files() as $file) {
+			if (fread(fopen($file, 'r'), 3) === self::BOM) {
+				$this->list[] = [$file, 1, self::BOM];
+			}
+		}
+
+		ob_start([$this, 'handler'], 1);
+	}
+
+
+	/** @internal */
+	public function handler(string $s, int $phase): string
+	{
+		$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+		if (isset($trace[0]['file'], $trace[0]['line'])) {
+			$stack = $trace;
+			unset($stack[0]['line'], $stack[0]['args']);
+			$i = count($this->list);
+			if ($i && $this->list[$i - 1][3] === $stack) {
+				$this->list[$i - 1][2] .= $s;
+			} else {
+				$this->list[] = [$trace[0]['file'], $trace[0]['line'], $s, $stack];
+			}
+		}
+
+		return $phase === PHP_OUTPUT_HANDLER_FINAL
+			? $this->renderHtml()
+			: '';
+	}
+
+
+	private function renderHtml(): string
+	{
+		$res = '';
+		foreach ($this->list as $item) {
+			$stack = [];
+			foreach (array_slice($item[3], 1) as $t) {
+				$t += ['class' => '', 'type' => '', 'function' => ''];
+				$stack[] = "$t[class]$t[type]$t[function]()"
+					. (isset($t['file'], $t['line']) ? ' in ' . basename($t['file']) . ":$t[line]" : '');
+			}
+
+			$res .= ''
+				. Helpers::editorLink($item[0], $item[1]) . ' '
+				. str_replace(self::BOM, 'BOM', Dumper::toHtml($item[2]))
+				. "
\n"; + } + + return $res . '
'; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Session/FileSession.php b/vendor/tracy/tracy/src/Tracy/Session/FileSession.php new file mode 100644 index 0000000..6dd85ce --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Session/FileSession.php @@ -0,0 +1,108 @@ +dir = $dir; + } + + + public function isAvailable(): bool + { + if (!$this->file) { + $this->open(); + } + + return true; + } + + + private function open(): void + { + $id = $_COOKIE[$this->cookieName] ?? null; + if ( + !is_string($id) + || !preg_match('#^\w{10}\z#i', $id) + || !($file = @fopen($path = $this->dir . '/' . self::FilePrefix . $id, 'r+')) // intentionally @ + ) { + $id = Helpers::createId(); + setcookie($this->cookieName, $id, time() + self::CookieLifetime, '/', '', secure: false, httponly: true); + + $file = @fopen($path = $this->dir . '/' . self::FilePrefix . $id, 'c+'); // intentionally @ + if ($file === false) { + throw new \RuntimeException("Unable to create file '$path'. " . error_get_last()['message']); + } + } + + if (!@flock($file, LOCK_EX)) { // intentionally @ + throw new \RuntimeException("Unable to acquire exclusive lock on '$path'. ", error_get_last()['message']); + } + + $this->file = $file; + $this->data = @unserialize(stream_get_contents($this->file)) ?: []; // @ - file may be empty + + if (mt_rand() / mt_getrandmax() < $this->gcProbability) { + $this->clean(); + } + } + + + public function &getData(): array + { + return $this->data; + } + + + public function clean(): void + { + $old = strtotime('-1 week'); + foreach (glob($this->dir . '/' . self::FilePrefix . '*') as $file) { + if (filemtime($file) < $old) { + unlink($file); + } + } + } + + + public function __destruct() + { + if (!$this->file) { + return; + } + + ftruncate($this->file, 0); + fseek($this->file, 0); + fwrite($this->file, serialize($this->data)); + flock($this->file, LOCK_UN); + fclose($this->file); + $this->file = null; + } +} diff --git a/vendor/tracy/tracy/src/Tracy/Session/NativeSession.php b/vendor/tracy/tracy/src/Tracy/Session/NativeSession.php new file mode 100644 index 0000000..9bec860 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/Session/NativeSession.php @@ -0,0 +1,28 @@ + { + e.target.closest('a[href^="editor:"]')?.setAttribute('target', '_blank'); + }, + true, + ); + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +if (!Tracy.helpers) { + init(); + Tracy.helpers = true; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/reset.css b/vendor/tracy/tracy/src/Tracy/assets/reset.css new file mode 100644 index 0000000..b0a6a6f --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/reset.css @@ -0,0 +1,386 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +:root { + --tracy-space: 16px; +} + +@media (max-width: 600px) { + :root { + --tracy-space: 8px; + } +} + +tracy-div:not(a b), +tracy-div:not(a b) * { + font: inherit; + line-height: inherit; + color: inherit; + background: transparent; + margin: 0; + padding: 0; + border: none; + text-align: inherit; + list-style: inherit; + opacity: 1; + border-radius: 0; + box-shadow: none; + text-shadow: none; + box-sizing: border-box; + text-decoration: none; + text-transform: inherit; + white-space: inherit; + float: none; + clear: none; + max-width: initial; + min-width: initial; + max-height: initial; + min-height: initial; +} + +tracy-div:not(a b) *:hover { + color: inherit; + background: transparent; +} + +tracy-div:not(a b) *:not(svg):not(img):not(table) { + width: initial; + height: initial; +} + +tracy-div:not(a b):before, +tracy-div:not(a b):after, +tracy-div:not(a b) *:before, +tracy-div:not(a b) *:after { + all: unset; +} + +tracy-div:not(a b) b, +tracy-div:not(a b) strong { + font-weight: bold; +} + +tracy-div:not(a b) small { + font-size: smaller; +} + +tracy-div:not(a b) i, +tracy-div:not(a b) em { + font-style: italic; +} + +tracy-div:not(a b) big { + font-size: larger; +} + +tracy-div:not(a b) small, +tracy-div:not(a b) sub, +tracy-div:not(a b) sup { + font-size: smaller; +} + +tracy-div:not(a b) ins { + text-decoration: underline; +} + +tracy-div:not(a b) del { + text-decoration: line-through; +} + +tracy-div:not(a b) table { + border-collapse: collapse; +} + +tracy-div:not(a b) pre { + font-family: monospace; + white-space: pre; +} + +tracy-div:not(a b) code, +tracy-div:not(a b) kbd, +tracy-div:not(a b) samp { + font-family: monospace; +} + +tracy-div:not(a b) input { + background-color: white; + padding: 1px; + border: 1px solid; +} + +tracy-div:not(a b) textarea { + background-color: white; + border: 1px solid; + padding: 2px; + white-space: pre-wrap; +} + +tracy-div:not(a b) select { + border: 1px solid; + white-space: pre; +} + +tracy-div:not(a b) article, +tracy-div:not(a b) aside, +tracy-div:not(a b) details, +tracy-div:not(a b) div, +tracy-div:not(a b) figcaption, +tracy-div:not(a b) footer, +tracy-div:not(a b) form, +tracy-div:not(a b) header, +tracy-div:not(a b) hgroup, +tracy-div:not(a b) main, +tracy-div:not(a b) nav, +tracy-div:not(a b) section, +tracy-div:not(a b) summary, +tracy-div:not(a b) pre, +tracy-div:not(a b) p, +tracy-div:not(a b) dl, +tracy-div:not(a b) dd, +tracy-div:not(a b) dt, +tracy-div:not(a b) blockquote, +tracy-div:not(a b) figure, +tracy-div:not(a b) address, +tracy-div:not(a b) h1, +tracy-div:not(a b) h2, +tracy-div:not(a b) h3, +tracy-div:not(a b) h4, +tracy-div:not(a b) h5, +tracy-div:not(a b) h6, +tracy-div:not(a b) ul, +tracy-div:not(a b) ol, +tracy-div:not(a b) li, +tracy-div:not(a b) hr { + display: block; +} + +tracy-div:not(a b) a, +tracy-div:not(a b) b, +tracy-div:not(a b) big, +tracy-div:not(a b) code, +tracy-div:not(a b) em, +tracy-div:not(a b) i, +tracy-div:not(a b) small, +tracy-div:not(a b) span, +tracy-div:not(a b) strong { + display: inline; +} + +tracy-div:not(a b) table { + display: table; +} + +tracy-div:not(a b) tr { + display: table-row; +} + +tracy-div:not(a b) col { + display: table-column; +} + +tracy-div:not(a b) colgroup { + display: table-column-group; +} + +tracy-div:not(a b) tbody { + display: table-row-group; +} + +tracy-div:not(a b) thead { + display: table-header-group; +} + +tracy-div:not(a b) tfoot { + display: table-footer-group; +} + +tracy-div:not(a b) td { + display: table-cell; +} + +tracy-div:not(a b) th { + display: table-cell; +} + + + +/* TableSort */ +tracy-div:not(a b) .tracy-sortable > :first-child > tr:first-child > * { + position: relative; +} + +tracy-div:not(a b) .tracy-sortable > :first-child > tr:first-child > *:hover:before { + position: absolute; + right: .3em; + content: "\21C5"; + opacity: .4; + font-weight: normal; +} + + +/* dump */ +tracy-div:not(a b) .tracy-dump div { + padding-left: 3ex; +} + +tracy-div:not(a b) .tracy-dump div div { + border-left: 1px solid rgba(0, 0, 0, .1); + margin-left: .5ex; +} + +tracy-div:not(a b) .tracy-dump div div:hover { + border-left-color: rgba(0, 0, 0, .25); +} + +tracy-div:not(a b) .tracy-dump { + background: #FDF5CE; + padding: .4em .7em; + border: 1px dotted silver; + overflow: auto; +} + +tracy-div:not(a b) table .tracy-dump.tracy-dump { /* overwrite .tracy-dump.tracy-light etc. */ + padding: 0; + margin: 0; + border: none; +} + +tracy-div:not(a b) .tracy-dump-location { + color: gray; + font-size: 80%; + text-decoration: none; + background: none; + opacity: .5; + float: right; + cursor: pointer; +} + +tracy-div:not(a b) .tracy-dump-location:hover, +tracy-div:not(a b) .tracy-dump-location:focus { + color: gray; + background: none; + opacity: 1; +} + +tracy-div:not(a b) .tracy-dump-array, +tracy-div:not(a b) .tracy-dump-object { + color: #C22; +} + +tracy-div:not(a b) .tracy-dump-string { + color: #35D; + white-space: break-spaces; +} + +tracy-div:not(a b) div.tracy-dump-string { + position: relative; + padding-left: 3.5ex; +} + +tracy-div:not(a b) .tracy-dump-lq { + margin-left: calc(-1ex - 1px); +} + +tracy-div:not(a b) div.tracy-dump-string:before { + content: ''; + position: absolute; + left: calc(3ex - 1px); + top: 1.5em; + bottom: 0; + border-left: 1px solid rgba(0, 0, 0, .1); +} + +tracy-div:not(a b) .tracy-dump-virtual span, +tracy-div:not(a b) .tracy-dump-dynamic span, +tracy-div:not(a b) .tracy-dump-string span { + color: rgba(0, 0, 0, 0.5); +} + +tracy-div:not(a b) .tracy-dump-virtual i, +tracy-div:not(a b) .tracy-dump-dynamic i, +tracy-div:not(a b) .tracy-dump-string i { + font-size: 80%; + font-style: normal; + color: rgba(0, 0, 0, 0.5); + user-select: none; +} + +tracy-div:not(a b) .tracy-dump-number { + color: #090; +} + +tracy-div:not(a b) .tracy-dump-null, +tracy-div:not(a b) .tracy-dump-bool { + color: #850; +} + +tracy-div:not(a b) .tracy-dump-virtual { + font-style: italic; +} + +tracy-div:not(a b) .tracy-dump-public::after { + content: ' pub'; +} + +tracy-div:not(a b) .tracy-dump-protected::after { + content: ' pro'; +} + +tracy-div:not(a b) .tracy-dump-private::after { + content: ' pri'; +} + +tracy-div:not(a b) .tracy-dump-public::after, +tracy-div:not(a b) .tracy-dump-protected::after, +tracy-div:not(a b) .tracy-dump-private::after, +tracy-div:not(a b) .tracy-dump-hash { + font-size: 85%; + color: rgba(0, 0, 0, 0.5); +} + +tracy-div:not(a b) .tracy-dump-indent { + display: none; +} + +tracy-div:not(a b) .tracy-dump-highlight { + background: #C22; + color: white; + border-radius: 2px; + padding: 0 2px; + margin: 0 -2px; +} + +tracy-div:not(a b) span[data-tracy-href] { + border-bottom: 1px dotted rgba(0, 0, 0, .2); +} + + +/* toggle */ +tracy-div:not(a b) .tracy-toggle:after { + content: ''; + display: inline-block; + vertical-align: middle; + line-height: 0; + border-top: .6ex solid; + border-right: .6ex solid transparent; + border-left: .6ex solid transparent; + transform: scale(1, 1.5); + margin: 0 .2ex 0 .7ex; + transition: .1s transform; + opacity: .5; +} + +tracy-div:not(a b) .tracy-toggle.tracy-collapsed:after { + transform: rotate(-90deg) scale(1, 1.5) translate(.1ex, 0); +} + + +/* tabs */ +tracy-div:not(a b) .tracy-tab-label { + user-select: none; +} + +tracy-div:not(a b) .tracy-tab-panel:not(.tracy-active) { + display: none; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/table-sort.css b/vendor/tracy/tracy/src/Tracy/assets/table-sort.css new file mode 100644 index 0000000..7967a64 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/table-sort.css @@ -0,0 +1,15 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-sortable > :first-child > tr:first-child > * { + position: relative; +} + +.tracy-sortable > :first-child > tr:first-child > *:hover:before { + position: absolute; + right: .3em; + content: "\21C5"; + opacity: .4; + font-weight: normal; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/table-sort.js b/vendor/tracy/tracy/src/Tracy/assets/table-sort.js new file mode 100644 index 0000000..39bae80 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/table-sort.js @@ -0,0 +1,39 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +// enables +class TableSort { + static init() { + document.documentElement.addEventListener('click', (e) => { + if ((window.getSelection().type !== 'Range') + && e.target.matches('.tracy-sortable > :first-child > tr:first-child *') + ) { + TableSort.sort(e.target.closest('td,th')); + } + }); + + TableSort.init = function () {}; + } + + static sort(tcell) { + let tbody = tcell.closest('table').tBodies[0]; + let preserveFirst = !tcell.closest('thead') && !tcell.parentNode.querySelectorAll('td').length; + let asc = !(tbody.tracyAsc === tcell.cellIndex); + tbody.tracyAsc = asc ? tcell.cellIndex : null; + let getText = (cell) => cell ? (cell.getAttribute('data-order') || cell.innerText) : ''; + + Array.from(tbody.children) + .slice(preserveFirst ? 1 : 0) + .sort((a, b) => (function (v1, v2) { + return v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) + ? v1 - v2 + : v1.toString().localeCompare(v2, undefined, { numeric: true, sensitivity: 'base' }); + }(getText((asc ? a : b).children[tcell.cellIndex]), getText((asc ? b : a).children[tcell.cellIndex])))) + .forEach((tr) => { tbody.appendChild(tr); }); + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +Tracy.TableSort = Tracy.TableSort || TableSort; diff --git a/vendor/tracy/tracy/src/Tracy/assets/tabs.css b/vendor/tracy/tracy/src/Tracy/assets/tabs.css new file mode 100644 index 0000000..9add853 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/tabs.css @@ -0,0 +1,11 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-tab-label { + user-select: none; +} + +.tracy-tab-panel:not(.tracy-active) { + display: none; +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/tabs.js b/vendor/tracy/tracy/src/Tracy/assets/tabs.js new file mode 100644 index 0000000..8ec2fe7 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/tabs.js @@ -0,0 +1,40 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +// enables .tracy-tabs, .tracy-tab-label, .tracy-tab-panel, .tracy-active +class Tabs { + static init() { + document.documentElement.addEventListener('click', (e) => { + let label, context; + if ( + !e.shiftKey && !e.ctrlKey && !e.metaKey + && (label = e.target.closest('.tracy-tab-label')) + && (context = e.target.closest('.tracy-tabs')) + ) { + Tabs.toggle(context, label); + e.preventDefault(); + e.stopImmediatePropagation(); + } + }); + + Tabs.init = function () {}; + } + + static toggle(context, label) { + let labels = context.querySelector('.tracy-tab-label').parentNode.querySelectorAll('.tracy-tab-label'), + panels = context.querySelector('.tracy-tab-panel').parentNode.querySelectorAll(':scope > .tracy-tab-panel'); + + for (let i = 0; i < labels.length; i++) { + labels[i].classList.toggle('tracy-active', labels[i] === label); + } + + for (let i = 0; i < panels.length; i++) { + panels[i].classList.toggle('tracy-active', labels[i] === label); + } + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +Tracy.Tabs = Tracy.Tabs || Tabs; diff --git a/vendor/tracy/tracy/src/Tracy/assets/toggle.css b/vendor/tracy/tracy/src/Tracy/assets/toggle.css new file mode 100644 index 0000000..acce8e4 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/toggle.css @@ -0,0 +1,35 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +.tracy-collapsed { + display: none; +} + +.tracy-toggle.tracy-collapsed { + display: inline; +} + +.tracy-toggle { + cursor: pointer; + user-select: none; + white-space: nowrap; +} + +.tracy-toggle:after { + content: ''; + display: inline-block; + vertical-align: middle; + line-height: 0; + border-top: .6ex solid; + border-right: .6ex solid transparent; + border-left: .6ex solid transparent; + transform: scale(1, 1.5); + margin: 0 .2ex 0 .7ex; + transition: .1s transform; + opacity: .5; +} + +.tracy-toggle.tracy-collapsed:after { + transform: rotate(-90deg) scale(1, 1.5) translate(.1ex, 0); +} diff --git a/vendor/tracy/tracy/src/Tracy/assets/toggle.js b/vendor/tracy/tracy/src/Tracy/assets/toggle.js new file mode 100644 index 0000000..aabefb5 --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/assets/toggle.js @@ -0,0 +1,116 @@ +/** + * This file is part of the Tracy (https://tracy.nette.org) + */ + +const MOVE_THRESHOLD = 100; + +// enables or toggling +class Toggle { + static init() { + let start; + document.documentElement.addEventListener('mousedown', (e) => { + start = [e.clientX, e.clientY]; + }); + + document.documentElement.addEventListener('click', (e) => { + let el; + if ( + !e.shiftKey && !e.ctrlKey && !e.metaKey + && (el = e.target.closest('.tracy-toggle')) + && Math.pow(start[0] - e.clientX, 2) + Math.pow(start[1] - e.clientY, 2) < MOVE_THRESHOLD + ) { + Toggle.toggle(el, undefined, e); + e.preventDefault(); + e.stopImmediatePropagation(); + } + }); + Toggle.init = function () {}; + } + + + // changes element visibility + static toggle(el, expand, e) { + let collapsed = el.classList.contains('tracy-collapsed'), + ref = el.getAttribute('data-tracy-ref') || el.getAttribute('href', 2), + dest = el; + + if (typeof expand === 'undefined') { + expand = collapsed; + } + + el.dispatchEvent(new CustomEvent('tracy-beforetoggle', { + bubbles: true, + detail: { collapsed: !expand, originalEvent: e }, + })); + + if (!ref || ref === '#') { + ref = '+'; + } else if (ref.substr(0, 1) === '#') { + dest = document; + } + ref = ref.match(/(\^\s*([^+\s]*)\s*)?(\+\s*(\S*)\s*)?(.*)/); + dest = ref[1] ? dest.parentNode : dest; + dest = ref[2] ? dest.closest(ref[2]) : dest; + dest = ref[3] ? Toggle.nextElement(dest.nextElementSibling, ref[4]) : dest; + dest = ref[5] ? dest.querySelector(ref[5]) : dest; + + el.classList.toggle('tracy-collapsed', !expand); + dest.classList.toggle('tracy-collapsed', !expand); + + el.dispatchEvent(new CustomEvent('tracy-toggle', { + bubbles: true, + detail: { relatedTarget: dest, collapsed: !expand, originalEvent: e }, + })); + } + + + // save & restore toggles + static persist(baseEl, restore) { + let saved = []; + baseEl.addEventListener('tracy-toggle', (e) => { + if (saved.indexOf(e.target) < 0) { + saved.push(e.target); + } + }); + + let toggles = JSON.parse(sessionStorage.getItem('tracy-toggles-' + baseEl.id)); + if (toggles && restore !== false) { + toggles.forEach((item) => { + let el = baseEl; + for (let i in item.path) { + if (!(el = el.children[item.path[i]])) { + return; + } + } + if (el.textContent === item.text) { + Toggle.toggle(el, item.expand); + } + }); + } + + window.addEventListener('pagehide', () => { + toggles = saved.map((el) => { + let item = { path: [], text: el.textContent, expand: !el.classList.contains('tracy-collapsed') }; + do { + item.path.unshift(Array.from(el.parentNode.children).indexOf(el)); + el = el.parentNode; + } while (el && el !== baseEl); + return item; + }); + sessionStorage.setItem('tracy-toggles-' + baseEl.id, JSON.stringify(toggles)); + }); + } + + + // finds next matching element + static nextElement(el, selector) { + while (el && selector && !el.matches(selector)) { + el = el.nextElementSibling; + } + return el; + } +} + + +let Tracy = window.Tracy = window.Tracy || {}; +Tracy.Toggle = Tracy.Toggle || Toggle; diff --git a/vendor/tracy/tracy/src/Tracy/functions.php b/vendor/tracy/tracy/src/Tracy/functions.php new file mode 100644 index 0000000..ab00b0d --- /dev/null +++ b/vendor/tracy/tracy/src/Tracy/functions.php @@ -0,0 +1,46 @@ +setStub("startBuffering(); +foreach ($iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__ . '/../../src', RecursiveDirectoryIterator::SKIP_DOTS)) as $file) { + echo "adding: {$iterator->getSubPathname()}\n"; + + $s = file_get_contents($file->getPathname()); + if (!str_contains($s, '@tracySkipLocation')) { + $s = php_strip_whitespace($file->getPathname()); + } + + if ($file->getExtension() === 'js') { + $s = compressJs($s); + + } elseif ($file->getExtension() === 'css') { + $s = compressCss($s); + + } elseif ($file->getExtension() === 'phtml') { + $s = preg_replace_callback('#(<(script|style).*(?)(.*)(getExtension() !== 'php') { + continue; + } + + $phar[$iterator->getSubPathname()] = $s; +} + +$phar->stopBuffering(); +$phar->compressFiles(Phar::GZ); + +echo "OK\n"; diff --git a/vendor/tracy/tracy/tools/open-in-editor/linux/install.sh b/vendor/tracy/tracy/tools/open-in-editor/linux/install.sh new file mode 100644 index 0000000..5a7bfb3 --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/linux/install.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# This shell script sets open-editor.sh as handler for editor:// protocol + +matches=0 +while read -r line +do + if [ "editor=" == "${line:0:7}" ]; then + matches=1 + break + fi +done < "open-editor.sh" + +if [ "$matches" == "0" ]; then + echo -e "\e[31;1mError: it seems like you have not set command to run your editor." + echo -e "Before install, set variable \`\$editor\` in file \`open-editor.sh\`.\e[0m" + exit 1 +fi + +# -------------------------------------------------------------- + +echo "[Desktop Entry] +Name=Tracy Open Editor +Exec=tracy-openeditor.sh %u +Terminal=false +NoDisplay=true +Type=Application +MimeType=x-scheme-handler/editor;" > tracy-openeditor.desktop + +chmod +x open-editor.sh +chmod +x tracy-openeditor.desktop + +sudo cp open-editor.sh /usr/bin/tracy-openeditor.sh +sudo xdg-desktop-menu install tracy-openeditor.desktop +sudo update-desktop-database +rm tracy-openeditor.desktop + +echo -e "\e[32;1mDone.\e[0m" diff --git a/vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh b/vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh new file mode 100644 index 0000000..69e37be --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/linux/open-editor.sh @@ -0,0 +1,109 @@ +#!/bin/bash +declare -A mapping + +# +# Configure your editor by setting the $editor variable: +# + +# Visual Studio Code +#editor='code --goto "$FILE":"$LINE"' +# Emacs +#editor='emacs +$LINE "$FILE"' +# gVim +#editor='gvim +$LINE "$FILE"' +# gEdit +#editor='gedit +$LINE "$FILE"' +# Pluma +#editor='pluma +$LINE "$FILE"' +# PHPStorm +# To enable PHPStorm command-line interface, folow this guide: https://www.jetbrains.com/help/phpstorm/working-with-the-ide-features-from-command-line.html +#editor='phpstorm --line $LINE "$FILE"' +# VS Codium +#editor='codium --goto "$FILE":"$LINE"' +# Visual Studio Code +#editor='code --goto "$FILE":"$LINE"' + +# +# Optionally configure custom mapping here: +# + +#mapping["/remotepath"]="/localpath" +#mapping["/mnt/d/"]="d:/" + +# +# Please, do not modify the code below. +# + +# Find and return URI parameter value. Or nothing, if the param is missing. +# Arguments: 1) URI, 2) Parameter name. +function get_param { + echo "$1" | sed -n -r "s/.*$2=([^&]*).*/\1/ip" +} + +if [[ -z "$editor" ]]; then + echo "You need to set the \$editor variable in file '`realpath $0`'" + exit +fi + +url=$1 +if [ "${url:0:9}" != "editor://" ]; then + exit +fi + +# Parse action and essential data from the URI. +regex='editor\:\/\/(open|create|fix)\/?\?(.*)' +action=`echo $url | sed -r "s/$regex/\1/i"` +uri_params=`echo $url | sed -r "s/$regex/\2/i"` + +file=`get_param $uri_params "file"` +line=`get_param $uri_params "line"` +search=`get_param $uri_params "search"` +replace=`get_param $uri_params "replace"` + +# Debug? +#echo "action '$action'" +#echo "file '$file'" +#echo "line '$line'" +#echo "search '$search'" +#echo "replace '$replace'" + +# Convert URI encoded codes to normal characters (e.g. '%2F' => '/'). +printf -v file "${file//%/\\x}" +# And escape double-quotes. +file=${file//\"/\\\"} + +# Apply custom mapping conversion. +for path in "${!mapping[@]}"; do + file="${file//$path/${mapping[$path]}}" +done + +# Action: Create a file (only if it does not already exist). +if [ "$action" == "create" ] && [[ ! -f "$file" ]]; then + mkdir -p $(dirname "$file") + touch "$file" + echo $replace > "$file" +fi + +# Action: Fix the file (if the file exists and while creating backup beforehand). +if [ "$action" == "fix" ]; then + + if [[ ! -f "$file" ]]; then + echo "Cannot fix non-existing file '$file'" + exit + fi + + # Backup the original file. + cp $file "$file.bak" + # Search and replace in place - only on the specified line. + sed -i "${line}s/${search}/${replace}/" $file + +fi + +# Format the command according to the selected editor. +command="${editor//\$FILE/$file}" +command="${command//\$LINE/$line}" + +# Debug? +#echo $command + +eval $command diff --git a/vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd b/vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd new file mode 100644 index 0000000..d841122 --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/windows/install.cmd @@ -0,0 +1,9 @@ +@echo off +:: This Windows batch file sets open-editor.js as handler for editor:// protocol + +if defined PROCESSOR_ARCHITEW6432 (set reg="%systemroot%\sysnative\reg.exe") else (set reg=reg) + +%reg% ADD HKCR\editor /ve /d "URL:editor Protocol" /f +%reg% ADD HKCR\editor /v "URL Protocol" /d "" /f +%reg% ADD HKCR\editor\shell\open\command /ve /d "wscript \"%~dp0open-editor.js\" \"%%1\"" /f +%reg% ADD HKLM\SOFTWARE\Policies\Google\Chrome\URLWhitelist /v "123" /d "editor://*" /f diff --git a/vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js b/vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js new file mode 100644 index 0000000..ac1093e --- /dev/null +++ b/vendor/tracy/tracy/tools/open-in-editor/windows/open-editor.js @@ -0,0 +1,84 @@ +var settings = { + + // PhpStorm + // editor: '"C:\\Program Files\\JetBrains\\PhpStorm 2018.1.2\\bin\\phpstorm64.exe" --line %line% "%file%"', + // title: 'PhpStorm', + + // NetBeans + // editor: '"C:\\Program Files\\NetBeans 8.1\\bin\\netbeans.exe" "%file%:%line%" --console suppress', + + // Nusphere PHPEd + // editor: '"C:\\Program Files\\NuSphere\\PhpED\\phped.exe" "%file%" --line=%line%', + + // SciTE + // editor: '"C:\\Program Files\\SciTE\\scite.exe" "-open:%file%" -goto:%line%', + + // EmEditor + // editor: '"C:\\Program Files\\EmEditor\\EmEditor.exe" "%file%" /l %line%', + + // PSPad Editor + // editor: '"C:\\Program Files\\PSPad editor\\PSPad.exe" -%line% "%file%"', + + // gVim + // editor: '"C:\\Program Files\\Vim\\vim73\\gvim.exe" "%file%" +%line%', + + // Sublime Text 2 + // editor: '"C:\\Program Files\\Sublime Text 2\\sublime_text.exe" "%file%:%line%"', + + // Visual Studio Code / VSCodium + // editor: '"C:\\Program Files\\Microsoft VS Code\\Code.exe" --goto "%file%:%line%"', + + mappings: { + // '/remotepath': '/localpath' + } +}; + + + +if (!settings.editor) { + WScript.Echo('Create variable "settings.editor" in ' + WScript.ScriptFullName); + WScript.Quit(); +} + +var url = WScript.Arguments(0); +var match = /^editor:\/\/(open|create|fix)\/?\?file=([^&]+)&line=(\d+)(?:&search=([^&]*)&replace=([^&]*))?/.exec(url); +if (!match) { + WScript.Echo('Unexpected URI ' + url); + WScript.Quit(); +} +for (var i in match) { + match[i] = decodeURIComponent(match[i]).replace(/\+/g, ' '); +} + +var action = match[1]; +var file = match[2]; +var line = match[3]; +var search = match[4]; +var replace = match[5]; + +var shell = new ActiveXObject('WScript.Shell'); +var fileSystem = new ActiveXObject('Scripting.FileSystemObject'); + +for (var id in settings.mappings) { + if (file.indexOf(id) === 0) { + file = settings.mappings[id] + file.substr(id.length); + break; + } +} + +if (action === 'create' && !fileSystem.FileExists(file)) { + shell.Run('cmd /c mkdir "' + fileSystem.GetParentFolderName(file) + '"', 0, 1); + fileSystem.CreateTextFile(file).Write(replace); + +} else if (action === 'fix') { + var lines = fileSystem.OpenTextFile(file).ReadAll().split('\n'); + lines[line-1] = lines[line-1].replace(search, replace); + fileSystem.OpenTextFile(file, 2).Write(lines.join('\n')); +} + +var command = settings.editor.replace(/%line%/, line).replace(/%file%/, file); +shell.Exec(command); + +if (settings.title) { + shell.AppActivate(settings.title); +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..4063cec --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import nette from '@nette/vite-plugin'; + +export default defineConfig({ + plugins: [ + nette({ + entry: 'main.js', + }), + ], + + build: { + emptyOutDir: true, + }, + + css: { + devSourcemap: true, + }, +}); diff --git a/www/.htaccess b/www/.htaccess new file mode 100644 index 0000000..2675d52 --- /dev/null +++ b/www/.htaccess @@ -0,0 +1,41 @@ +# Apache configuration file (see https://httpd.apache.org/docs/current/mod/quickreference.html) + +# Allow access to all resources by default +Require all granted + +# Disable directory listing for security reasons + + Options -Indexes + + +# Enable pretty URLs (removing the need for "index.php" in the URL) + + RewriteEngine On + + # Uncomment the next line if you want to set the base URL for rewrites + # RewriteBase / + + # Permit requests to the '.well-known' directory (used for SSL verification and more) + RewriteRule ^\.well-known/ - [L] + + # Block access to hidden files (starting with a dot) and URLs resembling WordPress admin paths + RewriteRule /\.|^\.|^wp-(login|admin|includes|content) - [F] + + # Force usage of HTTPS (secure connection). Uncomment if you have SSL setup. + # RewriteCond %{HTTPS} !on + # RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] + + # Return 404 for missing files with specific extensions (images, scripts, styles, archives) + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule \.(pdf|js|mjs|ico|gif|jpg|jpeg|png|webp|avif|svg|css|rar|zip|7z|tar\.gz|map|eot|ttf|otf|woff|woff2)$ - [L] + + # Front controller pattern - all requests are routed through index.php + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . index.php [L] + + +# Enable gzip compression for text files + + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/json application/xml application/rss+xml image/svg+xml + diff --git a/www/css/bootstrap.min.css b/www/css/bootstrap.min.css new file mode 100644 index 0000000..9018d8b --- /dev/null +++ b/www/css/bootstrap.min.css @@ -0,0 +1,11109 @@ +@charset "UTF-8"; +/*! + * Bootstrap v5.2.3 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Copyright 2011-2022 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-black: #000; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; + --bs-primary: #0d6efd; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-primary-rgb: 13, 110, 253; + --bs-secondary-rgb: 108, 117, 125; + --bs-success-rgb: 25, 135, 84; + --bs-info-rgb: 13, 202, 240; + --bs-warning-rgb: 255, 193, 7; + --bs-danger-rgb: 220, 53, 69; + --bs-light-rgb: 248, 249, 250; + --bs-dark-rgb: 33, 37, 41; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-body-color-rgb: 33, 37, 41; + --bs-body-bg-rgb: 255, 255, 255; + --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #212529; + --bs-body-bg: #fff; + --bs-border-width: 1px; + --bs-border-style: solid; + --bs-border-color: #dee2e6; + --bs-border-color-translucent: rgba(0, 0, 0, 0.175); + --bs-border-radius: 0.375rem; + --bs-border-radius-sm: 0.25rem; + --bs-border-radius-lg: 0.5rem; + --bs-border-radius-xl: 1rem; + --bs-border-radius-2xl: 2rem; + --bs-border-radius-pill: 50rem; + --bs-link-color: #0d6efd; + --bs-link-hover-color: #0a58ca; + --bs-code-color: #d63384; + --bs-highlight-bg: #fff3cd; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth; + } +} + +body { + margin: 0; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +hr { + margin: 1rem 0; + color: inherit; + border: 0; + border-top: 1px solid; + opacity: 0.25; +} + +h6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 { + margin-top: 0; + margin-bottom: 0.5rem; + font-weight: 500; + line-height: 1.2; +} + +h1, .h1 { + font-size: calc(1.375rem + 1.5vw); +} +@media (min-width: 1200px) { + h1, .h1 { + font-size: 2.5rem; + } +} + +h2, .h2 { + font-size: calc(1.325rem + 0.9vw); +} +@media (min-width: 1200px) { + h2, .h2 { + font-size: 2rem; + } +} + +h3, .h3 { + font-size: calc(1.3rem + 0.6vw); +} +@media (min-width: 1200px) { + h3, .h3 { + font-size: 1.75rem; + } +} + +h4, .h4 { + font-size: calc(1.275rem + 0.3vw); +} +@media (min-width: 1200px) { + h4, .h4 { + font-size: 1.5rem; + } +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title] { + text-decoration: underline dotted; + cursor: help; + text-decoration-skip-ink: none; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul { + padding-left: 2rem; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: 0.5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +b, +strong { + font-weight: bolder; +} + +small, .small { + font-size: 0.875em; +} + +mark, .mark { + padding: 0.1875em; + background-color: var(--bs-highlight-bg); +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +a { + color: var(--bs-link-color); + text-decoration: underline; +} +a:hover { + color: var(--bs-link-hover-color); +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; +} + +pre, +code, +kbd, +samp { + font-family: var(--bs-font-monospace); + font-size: 1em; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: 0.875em; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +code { + font-size: 0.875em; + color: var(--bs-code-color); + word-wrap: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.1875rem 0.375rem; + font-size: 0.875em; + color: var(--bs-body-bg); + background-color: var(--bs-body-color); + border-radius: 0.25rem; +} +kbd kbd { + padding: 0; + font-size: 1em; +} + +figure { + margin: 0 0 1rem; +} + +img, +svg { + vertical-align: middle; +} + +table { + caption-side: bottom; + border-collapse: collapse; +} + +caption { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: #6c757d; + text-align: left; +} + +th { + text-align: inherit; + text-align: -webkit-match-parent; +} + +thead, +tbody, +tfoot, +tr, +td, +th { + border-color: inherit; + border-style: solid; + border-width: 0; +} + +label { + display: inline-block; +} + +button { + border-radius: 0; +} + +button:focus:not(:focus-visible) { + outline: 0; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +select { + text-transform: none; +} + +[role=button] { + cursor: pointer; +} + +select { + word-wrap: normal; +} +select:disabled { + opacity: 1; +} + +[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { + display: none !important; +} + +button, +[type=button], +[type=reset], +[type=submit] { + -webkit-appearance: button; +} +button:not(:disabled), +[type=button]:not(:disabled), +[type=reset]:not(:disabled), +[type=submit]:not(:disabled) { + cursor: pointer; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +textarea { + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: 0.5rem; + font-size: calc(1.275rem + 0.3vw); + line-height: inherit; +} +@media (min-width: 1200px) { + legend { + font-size: 1.5rem; + } +} +legend + * { + clear: left; +} + +::-webkit-datetime-edit-fields-wrapper, +::-webkit-datetime-edit-text, +::-webkit-datetime-edit-minute, +::-webkit-datetime-edit-hour-field, +::-webkit-datetime-edit-day-field, +::-webkit-datetime-edit-month-field, +::-webkit-datetime-edit-year-field { + padding: 0; +} + +::-webkit-inner-spin-button { + height: auto; +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield; +} + +/* rtl:raw: +[type="tel"], +[type="url"], +[type="email"], +[type="number"] { + direction: ltr; +} +*/ +::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-color-swatch-wrapper { + padding: 0; +} + +::file-selector-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +iframe { + border: 0; +} + +summary { + display: list-item; + cursor: pointer; +} + +progress { + vertical-align: baseline; +} + +[hidden] { + display: none !important; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-1 { + font-size: 5rem; + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-2 { + font-size: 4.5rem; + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-3 { + font-size: 4rem; + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-4 { + font-size: 3.5rem; + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-5 { + font-size: 3rem; + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-6 { + font-size: 2.5rem; + } +} + +.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: 0.5rem; +} + +.initialism { + font-size: 0.875em; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} +.blockquote > :last-child { + margin-bottom: 0; +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: 0.875em; + color: #6c757d; +} +.blockquote-footer::before { + content: "— "; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid var(--bs-border-color); + border-radius: 0.375rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 0.875em; + color: #6c757d; +} + +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container-sm, .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container-md, .container-sm, .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container-lg, .container-md, .container-sm, .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1140px; + } +} +@media (min-width: 1400px) { + .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1320px; + } +} +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); +} +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.33333333%; +} + +.offset-2 { + margin-left: 16.66666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333333%; +} + +.offset-5 { + margin-left: 41.66666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333333%; +} + +.offset-8 { + margin-left: 66.66666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333333%; +} + +.offset-11 { + margin-left: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.33333333%; + } + .offset-sm-2 { + margin-left: 16.66666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.33333333%; + } + .offset-sm-5 { + margin-left: 41.66666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.33333333%; + } + .offset-sm-8 { + margin-left: 66.66666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.33333333%; + } + .offset-sm-11 { + margin-left: 91.66666667%; + } + .g-sm-0, + .gx-sm-0 { + --bs-gutter-x: 0; + } + .g-sm-0, + .gy-sm-0 { + --bs-gutter-y: 0; + } + .g-sm-1, + .gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + .g-sm-1, + .gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + .g-sm-2, + .gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + .g-sm-2, + .gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + .g-sm-3, + .gx-sm-3 { + --bs-gutter-x: 1rem; + } + .g-sm-3, + .gy-sm-3 { + --bs-gutter-y: 1rem; + } + .g-sm-4, + .gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + .g-sm-4, + .gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + .g-sm-5, + .gx-sm-5 { + --bs-gutter-x: 3rem; + } + .g-sm-5, + .gy-sm-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.33333333%; + } + .offset-md-2 { + margin-left: 16.66666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.33333333%; + } + .offset-md-5 { + margin-left: 41.66666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.33333333%; + } + .offset-md-8 { + margin-left: 66.66666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.33333333%; + } + .offset-md-11 { + margin-left: 91.66666667%; + } + .g-md-0, + .gx-md-0 { + --bs-gutter-x: 0; + } + .g-md-0, + .gy-md-0 { + --bs-gutter-y: 0; + } + .g-md-1, + .gx-md-1 { + --bs-gutter-x: 0.25rem; + } + .g-md-1, + .gy-md-1 { + --bs-gutter-y: 0.25rem; + } + .g-md-2, + .gx-md-2 { + --bs-gutter-x: 0.5rem; + } + .g-md-2, + .gy-md-2 { + --bs-gutter-y: 0.5rem; + } + .g-md-3, + .gx-md-3 { + --bs-gutter-x: 1rem; + } + .g-md-3, + .gy-md-3 { + --bs-gutter-y: 1rem; + } + .g-md-4, + .gx-md-4 { + --bs-gutter-x: 1.5rem; + } + .g-md-4, + .gy-md-4 { + --bs-gutter-y: 1.5rem; + } + .g-md-5, + .gx-md-5 { + --bs-gutter-x: 3rem; + } + .g-md-5, + .gy-md-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.33333333%; + } + .offset-lg-2 { + margin-left: 16.66666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.33333333%; + } + .offset-lg-5 { + margin-left: 41.66666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.33333333%; + } + .offset-lg-8 { + margin-left: 66.66666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.33333333%; + } + .offset-lg-11 { + margin-left: 91.66666667%; + } + .g-lg-0, + .gx-lg-0 { + --bs-gutter-x: 0; + } + .g-lg-0, + .gy-lg-0 { + --bs-gutter-y: 0; + } + .g-lg-1, + .gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + .g-lg-1, + .gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + .g-lg-2, + .gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + .g-lg-2, + .gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + .g-lg-3, + .gx-lg-3 { + --bs-gutter-x: 1rem; + } + .g-lg-3, + .gy-lg-3 { + --bs-gutter-y: 1rem; + } + .g-lg-4, + .gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + .g-lg-4, + .gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + .g-lg-5, + .gx-lg-5 { + --bs-gutter-x: 3rem; + } + .g-lg-5, + .gy-lg-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.33333333%; + } + .offset-xl-2 { + margin-left: 16.66666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.33333333%; + } + .offset-xl-5 { + margin-left: 41.66666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.33333333%; + } + .offset-xl-8 { + margin-left: 66.66666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.33333333%; + } + .offset-xl-11 { + margin-left: 91.66666667%; + } + .g-xl-0, + .gx-xl-0 { + --bs-gutter-x: 0; + } + .g-xl-0, + .gy-xl-0 { + --bs-gutter-y: 0; + } + .g-xl-1, + .gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xl-1, + .gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xl-2, + .gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xl-2, + .gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xl-3, + .gx-xl-3 { + --bs-gutter-x: 1rem; + } + .g-xl-3, + .gy-xl-3 { + --bs-gutter-y: 1rem; + } + .g-xl-4, + .gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xl-4, + .gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xl-5, + .gx-xl-5 { + --bs-gutter-x: 3rem; + } + .g-xl-5, + .gy-xl-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.3333333333%; + } + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.6666666667%; + } + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xxl-0 { + margin-left: 0; + } + .offset-xxl-1 { + margin-left: 8.33333333%; + } + .offset-xxl-2 { + margin-left: 16.66666667%; + } + .offset-xxl-3 { + margin-left: 25%; + } + .offset-xxl-4 { + margin-left: 33.33333333%; + } + .offset-xxl-5 { + margin-left: 41.66666667%; + } + .offset-xxl-6 { + margin-left: 50%; + } + .offset-xxl-7 { + margin-left: 58.33333333%; + } + .offset-xxl-8 { + margin-left: 66.66666667%; + } + .offset-xxl-9 { + margin-left: 75%; + } + .offset-xxl-10 { + margin-left: 83.33333333%; + } + .offset-xxl-11 { + margin-left: 91.66666667%; + } + .g-xxl-0, + .gx-xxl-0 { + --bs-gutter-x: 0; + } + .g-xxl-0, + .gy-xxl-0 { + --bs-gutter-y: 0; + } + .g-xxl-1, + .gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xxl-1, + .gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xxl-2, + .gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xxl-2, + .gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xxl-3, + .gx-xxl-3 { + --bs-gutter-x: 1rem; + } + .g-xxl-3, + .gy-xxl-3 { + --bs-gutter-y: 1rem; + } + .g-xxl-4, + .gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xxl-4, + .gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xxl-5, + .gx-xxl-5 { + --bs-gutter-x: 3rem; + } + .g-xxl-5, + .gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} +.table { + --bs-table-color: var(--bs-body-color); + --bs-table-bg: transparent; + --bs-table-border-color: var(--bs-border-color); + --bs-table-accent-bg: transparent; + --bs-table-striped-color: var(--bs-body-color); + --bs-table-striped-bg: rgba(0, 0, 0, 0.05); + --bs-table-active-color: var(--bs-body-color); + --bs-table-active-bg: rgba(0, 0, 0, 0.1); + --bs-table-hover-color: var(--bs-body-color); + --bs-table-hover-bg: rgba(0, 0, 0, 0.075); + width: 100%; + margin-bottom: 1rem; + color: var(--bs-table-color); + vertical-align: top; + border-color: var(--bs-table-border-color); +} +.table > :not(caption) > * > * { + padding: 0.5rem 0.5rem; + background-color: var(--bs-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg); +} +.table > tbody { + vertical-align: inherit; +} +.table > thead { + vertical-align: bottom; +} + +.table-group-divider { + border-top: 2px solid currentcolor; +} + +.caption-top { + caption-side: top; +} + +.table-sm > :not(caption) > * > * { + padding: 0.25rem 0.25rem; +} + +.table-bordered > :not(caption) > * { + border-width: 1px 0; +} +.table-bordered > :not(caption) > * > * { + border-width: 0 1px; +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0; +} +.table-borderless > :not(:first-child) { + border-top-width: 0; +} + +.table-striped > tbody > tr:nth-of-type(odd) > * { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color); +} + +.table-striped-columns > :not(caption) > tr > :nth-child(even) { + --bs-table-accent-bg: var(--bs-table-striped-bg); + color: var(--bs-table-striped-color); +} + +.table-active { + --bs-table-accent-bg: var(--bs-table-active-bg); + color: var(--bs-table-active-color); +} + +.table-hover > tbody > tr:hover > * { + --bs-table-accent-bg: var(--bs-table-hover-bg); + color: var(--bs-table-hover-color); +} + +.table-primary { + --bs-table-color: #000; + --bs-table-bg: #cfe2ff; + --bs-table-border-color: #bacbe6; + --bs-table-striped-bg: #c5d7f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bacbe6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfd1ec; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-secondary { + --bs-table-color: #000; + --bs-table-bg: #e2e3e5; + --bs-table-border-color: #cbccce; + --bs-table-striped-bg: #d7d8da; + --bs-table-striped-color: #000; + --bs-table-active-bg: #cbccce; + --bs-table-active-color: #000; + --bs-table-hover-bg: #d1d2d4; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-success { + --bs-table-color: #000; + --bs-table-bg: #d1e7dd; + --bs-table-border-color: #bcd0c7; + --bs-table-striped-bg: #c7dbd2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bcd0c7; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c1d6cc; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-info { + --bs-table-color: #000; + --bs-table-bg: #cff4fc; + --bs-table-border-color: #badce3; + --bs-table-striped-bg: #c5e8ef; + --bs-table-striped-color: #000; + --bs-table-active-bg: #badce3; + --bs-table-active-color: #000; + --bs-table-hover-bg: #bfe2e9; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-warning { + --bs-table-color: #000; + --bs-table-bg: #fff3cd; + --bs-table-border-color: #e6dbb9; + --bs-table-striped-bg: #f2e7c3; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6dbb9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ece1be; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-danger { + --bs-table-color: #000; + --bs-table-bg: #f8d7da; + --bs-table-border-color: #dfc2c4; + --bs-table-striped-bg: #eccccf; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfc2c4; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5c7ca; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-light { + --bs-table-color: #000; + --bs-table-bg: #f8f9fa; + --bs-table-border-color: #dfe0e1; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-dark { + --bs-table-color: #fff; + --bs-table-bg: #212529; + --bs-table-border-color: #373b3e; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +.form-label { + margin-bottom: 0.5rem; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; +} + +.form-text { + margin-top: 0.25rem; + font-size: 0.875em; + color: #6c757d; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + appearance: none; + border-radius: 0.375rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none; + } +} +.form-control[type=file] { + overflow: hidden; +} +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control:focus { + color: #212529; + background-color: #fff; + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-control::-webkit-date-and-time-value { + height: 1.5em; +} +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:disabled { + background-color: #e9ecef; + opacity: 1; +} +.form-control::file-selector-button { + padding: 0.375rem 0.75rem; + margin: -0.375rem -0.75rem; + margin-inline-end: 0.75rem; + color: #212529; + background-color: #e9ecef; + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: 1px; + border-radius: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control::file-selector-button { + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #dde0e3; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: 0.375rem 0; + margin-bottom: 0; + line-height: 1.5; + color: #212529; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} +.form-control-plaintext:focus { + outline: 0; +} +.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm { + min-height: calc(1.5em + 0.5rem + 2px); + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.25rem; +} +.form-control-sm::file-selector-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + margin-inline-end: 0.5rem; +} + +.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.5rem; +} +.form-control-lg::file-selector-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + margin-inline-end: 1rem; +} + +textarea.form-control { + min-height: calc(1.5em + 0.75rem + 2px); +} +textarea.form-control-sm { + min-height: calc(1.5em + 0.5rem + 2px); +} +textarea.form-control-lg { + min-height: calc(1.5em + 1rem + 2px); +} + +.form-control-color { + width: 3rem; + height: calc(1.5em + 0.75rem + 2px); + padding: 0.375rem; +} +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control-color::-moz-color-swatch { + border: 0 !important; + border-radius: 0.375rem; +} +.form-control-color::-webkit-color-swatch { + border-radius: 0.375rem; +} +.form-control-color.form-control-sm { + height: calc(1.5em + 0.5rem + 2px); +} +.form-control-color.form-control-lg { + height: calc(1.5em + 1rem + 2px); +} + +.form-select { + display: block; + width: 100%; + padding: 0.375rem 2.25rem 0.375rem 0.75rem; + -moz-padding-start: calc(0.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + background-color: #fff; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right 0.75rem center; + background-size: 16px 12px; + border: 1px solid #ced4da; + border-radius: 0.375rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-select { + transition: none; + } +} +.form-select:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: 0.75rem; + background-image: none; +} +.form-select:disabled { + background-color: #e9ecef; +} +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #212529; +} + +.form-select-sm { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + font-size: 0.875rem; + border-radius: 0.25rem; +} + +.form-select-lg { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 1rem; + font-size: 1.25rem; + border-radius: 0.5rem; +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: 0.125rem; +} +.form-check .form-check-input { + float: left; + margin-left: -1.5em; +} + +.form-check-reverse { + padding-right: 1.5em; + padding-left: 0; + text-align: right; +} +.form-check-reverse .form-check-input { + float: right; + margin-right: -1.5em; + margin-left: 0; +} + +.form-check-input { + width: 1em; + height: 1em; + margin-top: 0.25em; + vertical-align: top; + background-color: #fff; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: 1px solid rgba(0, 0, 0, 0.25); + appearance: none; + print-color-adjust: exact; +} +.form-check-input[type=checkbox] { + border-radius: 0.25em; +} +.form-check-input[type=radio] { + border-radius: 50%; +} +.form-check-input:active { + filter: brightness(90%); +} +.form-check-input:focus { + border-color: #86b7fe; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-check-input:checked { + background-color: #0d6efd; + border-color: #0d6efd; +} +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e"); +} +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); +} +.form-check-input[type=checkbox]:indeterminate { + background-color: #0d6efd; + border-color: #0d6efd; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); +} +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: 0.5; +} +.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { + cursor: default; + opacity: 0.5; +} + +.form-switch { + padding-left: 2.5em; +} +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + 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='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + background-position: left center; + border-radius: 2em; + transition: background-position 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-switch .form-check-input { + transition: none; + } +} +.form-switch .form-check-input:focus { + 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='%2386b7fe'/%3e%3c/svg%3e"); +} +.form-switch .form-check-input:checked { + background-position: right center; + 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"); +} +.form-switch.form-check-reverse { + padding-right: 2.5em; + padding-left: 0; +} +.form-switch.form-check-reverse .form-check-input { + margin-right: -2.5em; + margin-left: 0; +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem; +} + +.btn-check { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.btn-check[disabled] + .btn, .btn-check:disabled + .btn { + pointer-events: none; + filter: none; + opacity: 0.65; +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + appearance: none; +} +.form-range:focus { + outline: 0; +} +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25); +} +.form-range::-moz-focus-outer { + border: 0; +} +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -0.25rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-webkit-slider-thumb { + transition: none; + } +} +.form-range::-webkit-slider-thumb:active { + background-color: #b6d4fe; +} +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #0d6efd; + border: 0; + border-radius: 1rem; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-moz-range-thumb { + transition: none; + } +} +.form-range::-moz-range-thumb:active { + background-color: #b6d4fe; +} +.form-range::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.form-range:disabled { + pointer-events: none; +} +.form-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd; +} +.form-range:disabled::-moz-range-thumb { + background-color: #adb5bd; +} + +.form-floating { + position: relative; +} +.form-floating > .form-control, +.form-floating > .form-control-plaintext, +.form-floating > .form-select { + height: calc(3.5rem + 2px); + line-height: 1.25; +} +.form-floating > label { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 1rem 0.75rem; + overflow: hidden; + text-align: start; + text-overflow: ellipsis; + white-space: nowrap; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-floating > label { + transition: none; + } +} +.form-floating > .form-control, +.form-floating > .form-control-plaintext { + padding: 1rem 0.75rem; +} +.form-floating > .form-control::placeholder, +.form-floating > .form-control-plaintext::placeholder { + color: transparent; +} +.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown), +.form-floating > .form-control-plaintext:focus, +.form-floating > .form-control-plaintext:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:-webkit-autofill, +.form-floating > .form-control-plaintext:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:focus ~ label, +.form-floating > .form-control:not(:placeholder-shown) ~ label, +.form-floating > .form-control-plaintext ~ label, +.form-floating > .form-select ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:-webkit-autofill ~ label { + opacity: 0.65; + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control-plaintext ~ label { + border-width: 1px 0; +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100%; +} +.input-group > .form-control, +.input-group > .form-select, +.input-group > .form-floating { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0; +} +.input-group > .form-control:focus, +.input-group > .form-select:focus, +.input-group > .form-floating:focus-within { + z-index: 5; +} +.input-group .btn { + position: relative; + z-index: 2; +} +.input-group .btn:focus { + z-index: 5; +} + +.input-group-text { + display: flex; + align-items: center; + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.375rem; +} + +.input-group-lg > .form-control, +.input-group-lg > .form-select, +.input-group-lg > .input-group-text, +.input-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: 0.5rem; +} + +.input-group-sm > .form-control, +.input-group-sm > .form-select, +.input-group-sm > .input-group-text, +.input-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: 0.25rem; +} + +.input-group-lg > .form-select, +.input-group-sm > .form-select { + padding-right: 3rem; +} + +.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating), +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3), +.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control, +.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating), +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4), +.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control, +.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group > .form-floating:not(:first-child) > .form-control, +.input-group > .form-floating:not(:first-child) > .form-select { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: #198754; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: rgba(25, 135, 84, 0.9); + border-radius: 0.375rem; +} + +.was-validated :valid ~ .valid-feedback, +.was-validated :valid ~ .valid-tooltip, +.is-valid ~ .valid-feedback, +.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-control:valid, .form-control.is-valid { + border-color: #198754; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.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: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:valid:focus, .form-control.is-valid:focus { + border-color: #198754; + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} + +.was-validated .form-select:valid, .form-select.is-valid { + border-color: #198754; +} +.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.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-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:valid:focus, .form-select.is-valid:focus { + border-color: #198754; + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} + +.was-validated .form-control-color:valid, .form-control-color.is-valid { + width: calc(3rem + calc(1.5em + 0.75rem)); +} + +.was-validated .form-check-input:valid, .form-check-input.is-valid { + border-color: #198754; +} +.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { + background-color: #198754; +} +.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { + box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25); +} +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #198754; +} + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group > .form-control:not(:focus):valid, .input-group > .form-control:not(:focus).is-valid, +.was-validated .input-group > .form-select:not(:focus):valid, +.input-group > .form-select:not(:focus).is-valid, +.was-validated .input-group > .form-floating:not(:focus-within):valid, +.input-group > .form-floating:not(:focus-within).is-valid { + z-index: 3; +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: rgba(220, 53, 69, 0.9); + border-radius: 0.375rem; +} + +.was-validated :invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-tooltip, +.is-invalid ~ .invalid-feedback, +.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-control:invalid, .form-control.is-invalid { + border-color: #dc3545; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} + +.was-validated .form-select:invalid, .form-select.is-invalid { + border-color: #dc3545; +} +.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-position: right 0.75rem center, center right 2.25rem; + background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} + +.was-validated .form-control-color:invalid, .form-control-color.is-invalid { + width: calc(3rem + calc(1.5em + 0.75rem)); +} + +.was-validated .form-check-input:invalid, .form-check-input.is-invalid { + border-color: #dc3545; +} +.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { + background-color: #dc3545; +} +.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { + box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25); +} +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group > .form-control:not(:focus):invalid, .input-group > .form-control:not(:focus).is-invalid, +.was-validated .input-group > .form-select:not(:focus):invalid, +.input-group > .form-select:not(:focus).is-invalid, +.was-validated .input-group > .form-floating:not(:focus-within):invalid, +.input-group > .form-floating:not(:focus-within).is-invalid { + z-index: 4; +} + +.btn { + --bs-btn-padding-x: 0.75rem; + --bs-btn-padding-y: 0.375rem; + --bs-btn-font-family: ; + --bs-btn-font-size: 1rem; + --bs-btn-font-weight: 400; + --bs-btn-line-height: 1.5; + --bs-btn-color: #212529; + --bs-btn-bg: transparent; + --bs-btn-border-width: 1px; + --bs-btn-border-color: transparent; + --bs-btn-border-radius: 0.375rem; + --bs-btn-hover-border-color: transparent; + --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); + --bs-btn-disabled-opacity: 0.65; + --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5); + display: inline-block; + padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x); + font-family: var(--bs-btn-font-family); + font-size: var(--bs-btn-font-size); + font-weight: var(--bs-btn-font-weight); + line-height: var(--bs-btn-line-height); + color: var(--bs-btn-color); + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + user-select: none; + border: var(--bs-btn-border-width) solid var(--bs-btn-border-color); + border-radius: var(--bs-btn-border-radius); + background-color: var(--bs-btn-bg); + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); +} +.btn-check + .btn:hover { + color: var(--bs-btn-color); + background-color: var(--bs-btn-bg); + border-color: var(--bs-btn-border-color); +} +.btn:focus-visible { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-focus-box-shadow); +} +.btn-check:focus-visible + .btn { + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-focus-box-shadow); +} +.btn-check:checked + .btn, :not(.btn-check) + .btn:active, .btn:first-child:active, .btn.active, .btn.show { + color: var(--bs-btn-active-color); + background-color: var(--bs-btn-active-bg); + border-color: var(--bs-btn-active-border-color); +} +.btn-check:checked + .btn:focus-visible, :not(.btn-check) + .btn:active:focus-visible, .btn:first-child:active:focus-visible, .btn.active:focus-visible, .btn.show:focus-visible { + box-shadow: var(--bs-btn-focus-box-shadow); +} +.btn:disabled, .btn.disabled, fieldset:disabled .btn { + color: var(--bs-btn-disabled-color); + pointer-events: none; + background-color: var(--bs-btn-disabled-bg); + border-color: var(--bs-btn-disabled-border-color); + opacity: var(--bs-btn-disabled-opacity); +} + +.btn-primary { + --bs-btn-color: #fff; + --bs-btn-bg: #0d6efd; + --bs-btn-border-color: #0d6efd; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #0b5ed7; + --bs-btn-hover-border-color: #0a58ca; + --bs-btn-focus-shadow-rgb: 49, 132, 253; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #0a58ca; + --bs-btn-active-border-color: #0a53be; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #0d6efd; + --bs-btn-disabled-border-color: #0d6efd; +} + +.btn-secondary { + --bs-btn-color: #fff; + --bs-btn-bg: #6c757d; + --bs-btn-border-color: #6c757d; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #5c636a; + --bs-btn-hover-border-color: #565e64; + --bs-btn-focus-shadow-rgb: 130, 138, 145; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #565e64; + --bs-btn-active-border-color: #51585e; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #6c757d; + --bs-btn-disabled-border-color: #6c757d; +} + +.btn-success { + --bs-btn-color: #fff; + --bs-btn-bg: #198754; + --bs-btn-border-color: #198754; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #157347; + --bs-btn-hover-border-color: #146c43; + --bs-btn-focus-shadow-rgb: 60, 153, 110; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #146c43; + --bs-btn-active-border-color: #13653f; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #198754; + --bs-btn-disabled-border-color: #198754; +} + +.btn-info { + --bs-btn-color: #000; + --bs-btn-bg: #0dcaf0; + --bs-btn-border-color: #0dcaf0; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #31d2f2; + --bs-btn-hover-border-color: #25cff2; + --bs-btn-focus-shadow-rgb: 11, 172, 204; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #3dd5f3; + --bs-btn-active-border-color: #25cff2; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #000; + --bs-btn-disabled-bg: #0dcaf0; + --bs-btn-disabled-border-color: #0dcaf0; +} + +.btn-warning { + --bs-btn-color: #000; + --bs-btn-bg: #ffc107; + --bs-btn-border-color: #ffc107; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #ffca2c; + --bs-btn-hover-border-color: #ffc720; + --bs-btn-focus-shadow-rgb: 217, 164, 6; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #ffcd39; + --bs-btn-active-border-color: #ffc720; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #000; + --bs-btn-disabled-bg: #ffc107; + --bs-btn-disabled-border-color: #ffc107; +} + +.btn-danger { + --bs-btn-color: #fff; + --bs-btn-bg: #dc3545; + --bs-btn-border-color: #dc3545; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #bb2d3b; + --bs-btn-hover-border-color: #b02a37; + --bs-btn-focus-shadow-rgb: 225, 83, 97; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #b02a37; + --bs-btn-active-border-color: #a52834; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #dc3545; + --bs-btn-disabled-border-color: #dc3545; +} + +.btn-light { + --bs-btn-color: #000; + --bs-btn-bg: #f8f9fa; + --bs-btn-border-color: #f8f9fa; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #d3d4d5; + --bs-btn-hover-border-color: #c6c7c8; + --bs-btn-focus-shadow-rgb: 211, 212, 213; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #c6c7c8; + --bs-btn-active-border-color: #babbbc; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #000; + --bs-btn-disabled-bg: #f8f9fa; + --bs-btn-disabled-border-color: #f8f9fa; +} + +.btn-dark { + --bs-btn-color: #fff; + --bs-btn-bg: #212529; + --bs-btn-border-color: #212529; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #424649; + --bs-btn-hover-border-color: #373b3e; + --bs-btn-focus-shadow-rgb: 66, 70, 73; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #4d5154; + --bs-btn-active-border-color: #373b3e; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #212529; + --bs-btn-disabled-border-color: #212529; +} + +.btn-outline-primary { + --bs-btn-color: #0d6efd; + --bs-btn-border-color: #0d6efd; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #0d6efd; + --bs-btn-hover-border-color: #0d6efd; + --bs-btn-focus-shadow-rgb: 13, 110, 253; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #0d6efd; + --bs-btn-active-border-color: #0d6efd; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #0d6efd; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #0d6efd; + --bs-gradient: none; +} + +.btn-outline-secondary { + --bs-btn-color: #6c757d; + --bs-btn-border-color: #6c757d; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #6c757d; + --bs-btn-hover-border-color: #6c757d; + --bs-btn-focus-shadow-rgb: 108, 117, 125; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #6c757d; + --bs-btn-active-border-color: #6c757d; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #6c757d; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #6c757d; + --bs-gradient: none; +} + +.btn-outline-success { + --bs-btn-color: #198754; + --bs-btn-border-color: #198754; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #198754; + --bs-btn-hover-border-color: #198754; + --bs-btn-focus-shadow-rgb: 25, 135, 84; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #198754; + --bs-btn-active-border-color: #198754; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #198754; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #198754; + --bs-gradient: none; +} + +.btn-outline-info { + --bs-btn-color: #0dcaf0; + --bs-btn-border-color: #0dcaf0; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #0dcaf0; + --bs-btn-hover-border-color: #0dcaf0; + --bs-btn-focus-shadow-rgb: 13, 202, 240; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #0dcaf0; + --bs-btn-active-border-color: #0dcaf0; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #0dcaf0; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #0dcaf0; + --bs-gradient: none; +} + +.btn-outline-warning { + --bs-btn-color: #ffc107; + --bs-btn-border-color: #ffc107; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #ffc107; + --bs-btn-hover-border-color: #ffc107; + --bs-btn-focus-shadow-rgb: 255, 193, 7; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #ffc107; + --bs-btn-active-border-color: #ffc107; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #ffc107; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #ffc107; + --bs-gradient: none; +} + +.btn-outline-danger { + --bs-btn-color: #dc3545; + --bs-btn-border-color: #dc3545; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #dc3545; + --bs-btn-hover-border-color: #dc3545; + --bs-btn-focus-shadow-rgb: 220, 53, 69; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #dc3545; + --bs-btn-active-border-color: #dc3545; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #dc3545; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #dc3545; + --bs-gradient: none; +} + +.btn-outline-light { + --bs-btn-color: #f8f9fa; + --bs-btn-border-color: #f8f9fa; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #f8f9fa; + --bs-btn-hover-border-color: #f8f9fa; + --bs-btn-focus-shadow-rgb: 248, 249, 250; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #f8f9fa; + --bs-btn-active-border-color: #f8f9fa; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #f8f9fa; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #f8f9fa; + --bs-gradient: none; +} + +.btn-outline-dark { + --bs-btn-color: #212529; + --bs-btn-border-color: #212529; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #212529; + --bs-btn-hover-border-color: #212529; + --bs-btn-focus-shadow-rgb: 33, 37, 41; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #212529; + --bs-btn-active-border-color: #212529; + --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color: #212529; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #212529; + --bs-gradient: none; +} + +.btn-link { + --bs-btn-font-weight: 400; + --bs-btn-color: var(--bs-link-color); + --bs-btn-bg: transparent; + --bs-btn-border-color: transparent; + --bs-btn-hover-color: var(--bs-link-hover-color); + --bs-btn-hover-border-color: transparent; + --bs-btn-active-color: var(--bs-link-hover-color); + --bs-btn-active-border-color: transparent; + --bs-btn-disabled-color: #6c757d; + --bs-btn-disabled-border-color: transparent; + --bs-btn-box-shadow: none; + --bs-btn-focus-shadow-rgb: 49, 132, 253; + text-decoration: underline; +} +.btn-link:focus-visible { + color: var(--bs-btn-color); +} +.btn-link:hover { + color: var(--bs-btn-hover-color); +} + +.btn-lg, .btn-group-lg > .btn { + --bs-btn-padding-y: 0.5rem; + --bs-btn-padding-x: 1rem; + --bs-btn-font-size: 1.25rem; + --bs-btn-border-radius: 0.5rem; +} + +.btn-sm, .btn-group-sm > .btn { + --bs-btn-padding-y: 0.25rem; + --bs-btn-padding-x: 0.5rem; + --bs-btn-font-size: 0.875rem; + --bs-btn-border-radius: 0.25rem; +} + +.fade { + transition: opacity 0.15s linear; +} +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none; + } +} +.fade:not(.show) { + opacity: 0; +} + +.collapse:not(.show) { + display: none; +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none; + } +} +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing.collapse-horizontal { + transition: none; + } +} + +.dropup, +.dropend, +.dropdown, +.dropstart, +.dropup-center, +.dropdown-center { + position: relative; +} + +.dropdown-toggle { + white-space: nowrap; +} +.dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + --bs-dropdown-zindex: 1000; + --bs-dropdown-min-width: 10rem; + --bs-dropdown-padding-x: 0; + --bs-dropdown-padding-y: 0.5rem; + --bs-dropdown-spacer: 0.125rem; + --bs-dropdown-font-size: 1rem; + --bs-dropdown-color: #212529; + --bs-dropdown-bg: #fff; + --bs-dropdown-border-color: var(--bs-border-color-translucent); + --bs-dropdown-border-radius: 0.375rem; + --bs-dropdown-border-width: 1px; + --bs-dropdown-inner-border-radius: calc(0.375rem - 1px); + --bs-dropdown-divider-bg: var(--bs-border-color-translucent); + --bs-dropdown-divider-margin-y: 0.5rem; + --bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-dropdown-link-color: #212529; + --bs-dropdown-link-hover-color: #1e2125; + --bs-dropdown-link-hover-bg: #e9ecef; + --bs-dropdown-link-active-color: #fff; + --bs-dropdown-link-active-bg: #0d6efd; + --bs-dropdown-link-disabled-color: #adb5bd; + --bs-dropdown-item-padding-x: 1rem; + --bs-dropdown-item-padding-y: 0.25rem; + --bs-dropdown-header-color: #6c757d; + --bs-dropdown-header-padding-x: 1rem; + --bs-dropdown-header-padding-y: 0.5rem; + position: absolute; + z-index: var(--bs-dropdown-zindex); + display: none; + min-width: var(--bs-dropdown-min-width); + padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x); + margin: 0; + font-size: var(--bs-dropdown-font-size); + color: var(--bs-dropdown-color); + text-align: left; + list-style: none; + background-color: var(--bs-dropdown-bg); + background-clip: padding-box; + border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color); + border-radius: var(--bs-dropdown-border-radius); +} +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: var(--bs-dropdown-spacer); +} + +.dropdown-menu-start { + --bs-position: start; +} +.dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0; +} + +.dropdown-menu-end { + --bs-position: end; +} +.dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto; +} + +@media (min-width: 576px) { + .dropdown-menu-sm-start { + --bs-position: start; + } + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-sm-end { + --bs-position: end; + } + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start; + } + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-md-end { + --bs-position: end; + } + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start; + } + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-lg-end { + --bs-position: end; + } + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start; + } + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-xl-end { + --bs-position: end; + } + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start; + } + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-xxl-end { + --bs-position: end; + } + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: var(--bs-dropdown-spacer); +} +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: var(--bs-dropdown-spacer); +} +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropend .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropend .dropdown-toggle::after { + vertical-align: 0; +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: var(--bs-dropdown-spacer); +} +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropstart .dropdown-toggle::after { + display: none; +} +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropstart .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropstart .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: var(--bs-dropdown-divider-margin-y) 0; + overflow: hidden; + border-top: 1px solid var(--bs-dropdown-divider-bg); + opacity: 1; +} + +.dropdown-item { + display: block; + width: 100%; + padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); + clear: both; + font-weight: 400; + color: var(--bs-dropdown-link-color); + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:hover, .dropdown-item:focus { + color: var(--bs-dropdown-link-hover-color); + background-color: var(--bs-dropdown-link-hover-bg); +} +.dropdown-item.active, .dropdown-item:active { + color: var(--bs-dropdown-link-active-color); + text-decoration: none; + background-color: var(--bs-dropdown-link-active-bg); +} +.dropdown-item.disabled, .dropdown-item:disabled { + color: var(--bs-dropdown-link-disabled-color); + pointer-events: none; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x); + margin-bottom: 0; + font-size: 0.875rem; + color: var(--bs-dropdown-header-color); + white-space: nowrap; +} + +.dropdown-item-text { + display: block; + padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); + color: var(--bs-dropdown-link-color); +} + +.dropdown-menu-dark { + --bs-dropdown-color: #dee2e6; + --bs-dropdown-bg: #343a40; + --bs-dropdown-border-color: var(--bs-border-color-translucent); + --bs-dropdown-box-shadow: ; + --bs-dropdown-link-color: #dee2e6; + --bs-dropdown-link-hover-color: #fff; + --bs-dropdown-divider-bg: var(--bs-border-color-translucent); + --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15); + --bs-dropdown-link-active-color: #fff; + --bs-dropdown-link-active-bg: #0d6efd; + --bs-dropdown-link-disabled-color: #adb5bd; + --bs-dropdown-header-color: #adb5bd; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + flex: 1 1 auto; +} +.btn-group > .btn-check:checked + .btn, +.btn-group > .btn-check:focus + .btn, +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn-check:checked + .btn, +.btn-group-vertical > .btn-check:focus + .btn, +.btn-group-vertical > .btn:hover, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group { + border-radius: 0.375rem; +} +.btn-group > :not(.btn-check:first-child) + .btn, +.btn-group > .btn-group:not(:first-child) { + margin-left: -1px; +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn.dropdown-toggle-split:first-child, +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:nth-child(n+3), +.btn-group > :not(.btn-check) + .btn, +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after { + margin-left: 0; +} +.dropstart .dropdown-toggle-split::before { + margin-right: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + width: 100%; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) { + margin-top: -1px; +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn ~ .btn, +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav { + --bs-nav-link-padding-x: 1rem; + --bs-nav-link-padding-y: 0.5rem; + --bs-nav-link-font-weight: ; + --bs-nav-link-color: var(--bs-link-color); + --bs-nav-link-hover-color: var(--bs-link-hover-color); + --bs-nav-link-disabled-color: #6c757d; + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x); + font-size: var(--bs-nav-link-font-size); + font-weight: var(--bs-nav-link-font-weight); + color: var(--bs-nav-link-color); + text-decoration: none; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .nav-link { + transition: none; + } +} +.nav-link:hover, .nav-link:focus { + color: var(--bs-nav-link-hover-color); +} +.nav-link.disabled { + color: var(--bs-nav-link-disabled-color); + pointer-events: none; + cursor: default; +} + +.nav-tabs { + --bs-nav-tabs-border-width: 1px; + --bs-nav-tabs-border-color: #dee2e6; + --bs-nav-tabs-border-radius: 0.375rem; + --bs-nav-tabs-link-hover-border-color: #e9ecef #e9ecef #dee2e6; + --bs-nav-tabs-link-active-color: #495057; + --bs-nav-tabs-link-active-bg: #fff; + --bs-nav-tabs-link-active-border-color: #dee2e6 #dee2e6 #fff; + border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color); +} +.nav-tabs .nav-link { + margin-bottom: calc(-1 * var(--bs-nav-tabs-border-width)); + background: none; + border: var(--bs-nav-tabs-border-width) solid transparent; + border-top-left-radius: var(--bs-nav-tabs-border-radius); + border-top-right-radius: var(--bs-nav-tabs-border-radius); +} +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + isolation: isolate; + border-color: var(--bs-nav-tabs-link-hover-border-color); +} +.nav-tabs .nav-link.disabled, .nav-tabs .nav-link:disabled { + color: var(--bs-nav-link-disabled-color); + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: var(--bs-nav-tabs-link-active-color); + background-color: var(--bs-nav-tabs-link-active-bg); + border-color: var(--bs-nav-tabs-link-active-border-color); +} +.nav-tabs .dropdown-menu { + margin-top: calc(-1 * var(--bs-nav-tabs-border-width)); + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills { + --bs-nav-pills-border-radius: 0.375rem; + --bs-nav-pills-link-active-color: #fff; + --bs-nav-pills-link-active-bg: #0d6efd; +} +.nav-pills .nav-link { + background: none; + border: 0; + border-radius: var(--bs-nav-pills-border-radius); +} +.nav-pills .nav-link:disabled { + color: var(--bs-nav-link-disabled-color); + background-color: transparent; + border-color: transparent; +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: var(--bs-nav-pills-link-active-color); + background-color: var(--bs-nav-pills-link-active-bg); +} + +.nav-fill > .nav-link, +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center; +} + +.nav-justified > .nav-link, +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; +} + +.nav-fill .nav-item .nav-link, +.nav-justified .nav-item .nav-link { + width: 100%; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +.navbar { + --bs-navbar-padding-x: 0; + --bs-navbar-padding-y: 0.5rem; + --bs-navbar-color: rgba(0, 0, 0, 0.55); + --bs-navbar-hover-color: rgba(0, 0, 0, 0.7); + --bs-navbar-disabled-color: rgba(0, 0, 0, 0.3); + --bs-navbar-active-color: rgba(0, 0, 0, 0.9); + --bs-navbar-brand-padding-y: 0.3125rem; + --bs-navbar-brand-margin-end: 1rem; + --bs-navbar-brand-font-size: 1.25rem; + --bs-navbar-brand-color: rgba(0, 0, 0, 0.9); + --bs-navbar-brand-hover-color: rgba(0, 0, 0, 0.9); + --bs-navbar-nav-link-padding-x: 0.5rem; + --bs-navbar-toggler-padding-y: 0.25rem; + --bs-navbar-toggler-padding-x: 0.75rem; + --bs-navbar-toggler-font-size: 1.25rem; + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + --bs-navbar-toggler-border-color: rgba(0, 0, 0, 0.1); + --bs-navbar-toggler-border-radius: 0.375rem; + --bs-navbar-toggler-focus-width: 0.25rem; + --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out; + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x); +} +.navbar > .container, +.navbar > .container-fluid, +.navbar > .container-sm, +.navbar > .container-md, +.navbar > .container-lg, +.navbar > .container-xl, +.navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between; +} +.navbar-brand { + padding-top: var(--bs-navbar-brand-padding-y); + padding-bottom: var(--bs-navbar-brand-padding-y); + margin-right: var(--bs-navbar-brand-margin-end); + font-size: var(--bs-navbar-brand-font-size); + color: var(--bs-navbar-brand-color); + text-decoration: none; + white-space: nowrap; +} +.navbar-brand:hover, .navbar-brand:focus { + color: var(--bs-navbar-brand-hover-color); +} + +.navbar-nav { + --bs-nav-link-padding-x: 0; + --bs-nav-link-padding-y: 0.5rem; + --bs-nav-link-font-weight: ; + --bs-nav-link-color: var(--bs-navbar-color); + --bs-nav-link-hover-color: var(--bs-navbar-hover-color); + --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color); + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .show > .nav-link, +.navbar-nav .nav-link.active { + color: var(--bs-navbar-active-color); +} +.navbar-nav .dropdown-menu { + position: static; +} + +.navbar-text { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: var(--bs-navbar-color); +} +.navbar-text a, +.navbar-text a:hover, +.navbar-text a:focus { + color: var(--bs-navbar-active-color); +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center; +} + +.navbar-toggler { + padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x); + font-size: var(--bs-navbar-toggler-font-size); + line-height: 1; + color: var(--bs-navbar-color); + background-color: transparent; + border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color); + border-radius: var(--bs-navbar-toggler-border-radius); + transition: var(--bs-navbar-toggler-transition); +} +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none; + } +} +.navbar-toggler:hover { + text-decoration: none; +} +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width); +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-image: var(--bs-navbar-toggler-icon-bg); + background-repeat: no-repeat; + background-position: center; + background-size: 100%; +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height, 75vh); + overflow-y: auto; +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none; + } + .navbar-expand-sm .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-sm .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-md .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none; + } + .navbar-expand-md .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-md .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none; + } + .navbar-expand-lg .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-lg .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none; + } + .navbar-expand-xl .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-xl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xxl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xxl .navbar-toggler { + display: none; + } + .navbar-expand-xxl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none; + } + .navbar-expand-xxl .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-xxl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start; +} +.navbar-expand .navbar-nav { + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); +} +.navbar-expand .navbar-nav-scroll { + overflow: visible; +} +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-expand .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + transition: none; +} +.navbar-expand .offcanvas .offcanvas-header { + display: none; +} +.navbar-expand .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; +} + +.navbar-dark { + --bs-navbar-color: rgba(255, 255, 255, 0.55); + --bs-navbar-hover-color: rgba(255, 255, 255, 0.75); + --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25); + --bs-navbar-active-color: #fff; + --bs-navbar-brand-color: #fff; + --bs-navbar-brand-hover-color: #fff; + --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1); + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} + +.card { + --bs-card-spacer-y: 1rem; + --bs-card-spacer-x: 1rem; + --bs-card-title-spacer-y: 0.5rem; + --bs-card-border-width: 1px; + --bs-card-border-color: var(--bs-border-color-translucent); + --bs-card-border-radius: 0.375rem; + --bs-card-box-shadow: ; + --bs-card-inner-border-radius: calc(0.375rem - 1px); + --bs-card-cap-padding-y: 0.5rem; + --bs-card-cap-padding-x: 1rem; + --bs-card-cap-bg: rgba(0, 0, 0, 0.03); + --bs-card-cap-color: ; + --bs-card-height: ; + --bs-card-color: ; + --bs-card-bg: #fff; + --bs-card-img-overlay-padding: 1rem; + --bs-card-group-margin: 0.75rem; + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + height: var(--bs-card-height); + word-wrap: break-word; + background-color: var(--bs-card-bg); + background-clip: border-box; + border: var(--bs-card-border-width) solid var(--bs-card-border-color); + border-radius: var(--bs-card-border-radius); +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group { + border-top: inherit; + border-bottom: inherit; +} +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: var(--bs-card-inner-border-radius); + border-top-right-radius: var(--bs-card-inner-border-radius); +} +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: var(--bs-card-inner-border-radius); + border-bottom-left-radius: var(--bs-card-inner-border-radius); +} +.card > .card-header + .list-group, +.card > .list-group + .card-footer { + border-top: 0; +} + +.card-body { + flex: 1 1 auto; + padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x); + color: var(--bs-card-color); +} + +.card-title { + margin-bottom: var(--bs-card-title-spacer-y); +} + +.card-subtitle { + margin-top: calc(-0.5 * var(--bs-card-title-spacer-y)); + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link + .card-link { + margin-left: var(--bs-card-spacer-x); +} + +.card-header { + padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); + margin-bottom: 0; + color: var(--bs-card-cap-color); + background-color: var(--bs-card-cap-bg); + border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color); +} +.card-header:first-child { + border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0; +} + +.card-footer { + padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); + color: var(--bs-card-cap-color); + background-color: var(--bs-card-cap-bg); + border-top: var(--bs-card-border-width) solid var(--bs-card-border-color); +} +.card-footer:last-child { + border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius); +} + +.card-header-tabs { + margin-right: calc(-0.5 * var(--bs-card-cap-padding-x)); + margin-bottom: calc(-1 * var(--bs-card-cap-padding-y)); + margin-left: calc(-0.5 * var(--bs-card-cap-padding-x)); + border-bottom: 0; +} +.card-header-tabs .nav-link.active { + background-color: var(--bs-card-bg); + border-bottom-color: var(--bs-card-bg); +} + +.card-header-pills { + margin-right: calc(-0.5 * var(--bs-card-cap-padding-x)); + margin-left: calc(-0.5 * var(--bs-card-cap-padding-x)); +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: var(--bs-card-img-overlay-padding); + border-radius: var(--bs-card-inner-border-radius); +} + +.card-img, +.card-img-top, +.card-img-bottom { + width: 100%; +} + +.card-img, +.card-img-top { + border-top-left-radius: var(--bs-card-inner-border-radius); + border-top-right-radius: var(--bs-card-inner-border-radius); +} + +.card-img, +.card-img-bottom { + border-bottom-right-radius: var(--bs-card-inner-border-radius); + border-bottom-left-radius: var(--bs-card-inner-border-radius); +} + +.card-group > .card { + margin-bottom: var(--bs-card-group-margin); +} +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap; + } + .card-group > .card { + 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-img-top, + .card-group > .card:not(:last-child) .card-header { + border-top-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-bottom, + .card-group > .card:not(:last-child) .card-footer { + 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-img-top, + .card-group > .card:not(:first-child) .card-header { + border-top-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-bottom, + .card-group > .card:not(:first-child) .card-footer { + border-bottom-left-radius: 0; + } +} + +.accordion { + --bs-accordion-color: #212529; + --bs-accordion-bg: #fff; + --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; + --bs-accordion-border-color: var(--bs-border-color); + --bs-accordion-border-width: 1px; + --bs-accordion-border-radius: 0.375rem; + --bs-accordion-inner-border-radius: calc(0.375rem - 1px); + --bs-accordion-btn-padding-x: 1.25rem; + --bs-accordion-btn-padding-y: 1rem; + --bs-accordion-btn-color: #212529; + --bs-accordion-btn-bg: var(--bs-accordion-bg); + --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-icon-width: 1.25rem; + --bs-accordion-btn-icon-transform: rotate(-180deg); + --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out; + --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-focus-border-color: #86b7fe; + --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + --bs-accordion-body-padding-x: 1.25rem; + --bs-accordion-body-padding-y: 1rem; + --bs-accordion-active-color: #0c63e4; + --bs-accordion-active-bg: #e7f1ff; +} + +.accordion-button, .accordion-button-2 { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x); + font-size: 1rem; + color: var(--bs-accordion-btn-color); + text-align: left; + background-color: var(--bs-accordion-btn-bg); + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: var(--bs-accordion-transition); +} +@media (prefers-reduced-motion: reduce) { + .accordion-button, .accordion-button-2 { + transition: none; + } +} +.accordion-button:not(.collapsed), .accordion-button-2:not(.collapsed) { + color: var(--bs-accordion-active-color); + background-color: var(--bs-accordion-active-bg); + box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color); +} +.accordion-button:not(.collapsed)::after, .accordion-button-2:not(.collapsed)::after { + background-image: var(--bs-accordion-btn-active-icon); + transform: var(--bs-accordion-btn-icon-transform); +} +.accordion-button::after, .accordion-button-2::after { + flex-shrink: 0; + width: var(--bs-accordion-btn-icon-width); + height: var(--bs-accordion-btn-icon-width); + margin-left: auto; + content: ""; + background-image: var(--bs-accordion-btn-icon); + background-repeat: no-repeat; + background-size: var(--bs-accordion-btn-icon-width); + transition: var(--bs-accordion-btn-icon-transition); +} +@media (prefers-reduced-motion: reduce) { + .accordion-button::after, .accordion-button-2::after { + transition: none; + } +} +.accordion-button:hover, .accordion-button-2:hover { + z-index: 2; +} +.accordion-button:focus, .accordion-button-2:focus { + z-index: 3; + border-color: var(--bs-accordion-btn-focus-border-color); + outline: 0; + box-shadow: var(--bs-accordion-btn-focus-box-shadow); +} + +.accordion-header { + margin-bottom: 0; +} + +.accordion-item { + color: var(--bs-accordion-color); + background-color: var(--bs-accordion-bg); + border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color); +} +.accordion-item:first-of-type { + border-top-left-radius: var(--bs-accordion-border-radius); + border-top-right-radius: var(--bs-accordion-border-radius); +} +.accordion-item:first-of-type .accordion-button, .accordion-item:first-of-type .accordion-button-2 { + border-top-left-radius: var(--bs-accordion-inner-border-radius); + border-top-right-radius: var(--bs-accordion-inner-border-radius); +} +.accordion-item:not(:first-of-type) { + border-top: 0; +} +.accordion-item:last-of-type { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius); +} +.accordion-item:last-of-type .accordion-button.collapsed, .accordion-item:last-of-type .collapsed.accordion-button-2 { + border-bottom-right-radius: var(--bs-accordion-inner-border-radius); + border-bottom-left-radius: var(--bs-accordion-inner-border-radius); +} +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius); +} + +.accordion-body { + padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x); +} + +.accordion-flush .accordion-collapse { + border-width: 0; +} +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} +.accordion-flush .accordion-item:first-child { + border-top: 0; +} +.accordion-flush .accordion-item:last-child { + border-bottom: 0; +} +.accordion-flush .accordion-item .accordion-button, .accordion-flush .accordion-item .accordion-button-2, .accordion-flush .accordion-item .accordion-button.collapsed { + border-radius: 0; +} + +.breadcrumb { + --bs-breadcrumb-padding-x: 0; + --bs-breadcrumb-padding-y: 0; + --bs-breadcrumb-margin-bottom: 1rem; + --bs-breadcrumb-bg: ; + --bs-breadcrumb-border-radius: ; + --bs-breadcrumb-divider-color: #6c757d; + --bs-breadcrumb-item-padding-x: 0.5rem; + --bs-breadcrumb-item-active-color: #6c757d; + display: flex; + flex-wrap: wrap; + padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x); + margin-bottom: var(--bs-breadcrumb-margin-bottom); + font-size: var(--bs-breadcrumb-font-size); + list-style: none; + background-color: var(--bs-breadcrumb-bg); + border-radius: var(--bs-breadcrumb-border-radius); +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: var(--bs-breadcrumb-item-padding-x); +} +.breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: var(--bs-breadcrumb-item-padding-x); + color: var(--bs-breadcrumb-divider-color); + content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */; +} +.breadcrumb-item.active { + color: var(--bs-breadcrumb-item-active-color); +} + +.pagination { + --bs-pagination-padding-x: 0.75rem; + --bs-pagination-padding-y: 0.375rem; + --bs-pagination-font-size: 1rem; + --bs-pagination-color: var(--bs-link-color); + --bs-pagination-bg: #fff; + --bs-pagination-border-width: 1px; + --bs-pagination-border-color: #dee2e6; + --bs-pagination-border-radius: 0.375rem; + --bs-pagination-hover-color: var(--bs-link-hover-color); + --bs-pagination-hover-bg: #e9ecef; + --bs-pagination-hover-border-color: #dee2e6; + --bs-pagination-focus-color: var(--bs-link-hover-color); + --bs-pagination-focus-bg: #e9ecef; + --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + --bs-pagination-active-color: #fff; + --bs-pagination-active-bg: #0d6efd; + --bs-pagination-active-border-color: #0d6efd; + --bs-pagination-disabled-color: #6c757d; + --bs-pagination-disabled-bg: #fff; + --bs-pagination-disabled-border-color: #dee2e6; + display: flex; + padding-left: 0; + list-style: none; +} + +.page-link { + position: relative; + display: block; + padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x); + font-size: var(--bs-pagination-font-size); + color: var(--bs-pagination-color); + text-decoration: none; + background-color: var(--bs-pagination-bg); + border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color); + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .page-link { + transition: none; + } +} +.page-link:hover { + z-index: 2; + color: var(--bs-pagination-hover-color); + background-color: var(--bs-pagination-hover-bg); + border-color: var(--bs-pagination-hover-border-color); +} +.page-link:focus { + z-index: 3; + color: var(--bs-pagination-focus-color); + background-color: var(--bs-pagination-focus-bg); + outline: 0; + box-shadow: var(--bs-pagination-focus-box-shadow); +} +.page-link.active, .active > .page-link { + z-index: 3; + color: var(--bs-pagination-active-color); + background-color: var(--bs-pagination-active-bg); + border-color: var(--bs-pagination-active-border-color); +} +.page-link.disabled, .disabled > .page-link { + color: var(--bs-pagination-disabled-color); + pointer-events: none; + background-color: var(--bs-pagination-disabled-bg); + border-color: var(--bs-pagination-disabled-border-color); +} + +.page-item:not(:first-child) .page-link { + margin-left: -1px; +} +.page-item:first-child .page-link { + border-top-left-radius: var(--bs-pagination-border-radius); + border-bottom-left-radius: var(--bs-pagination-border-radius); +} +.page-item:last-child .page-link { + border-top-right-radius: var(--bs-pagination-border-radius); + border-bottom-right-radius: var(--bs-pagination-border-radius); +} + +.pagination-lg { + --bs-pagination-padding-x: 1.5rem; + --bs-pagination-padding-y: 0.75rem; + --bs-pagination-font-size: 1.25rem; + --bs-pagination-border-radius: 0.5rem; +} + +.pagination-sm { + --bs-pagination-padding-x: 0.5rem; + --bs-pagination-padding-y: 0.25rem; + --bs-pagination-font-size: 0.875rem; + --bs-pagination-border-radius: 0.25rem; +} + +.badge { + --bs-badge-padding-x: 0.65em; + --bs-badge-padding-y: 0.35em; + --bs-badge-font-size: 0.75em; + --bs-badge-font-weight: 700; + --bs-badge-color: #fff; + --bs-badge-border-radius: 0.375rem; + display: inline-block; + padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); + font-size: var(--bs-badge-font-size); + font-weight: var(--bs-badge-font-weight); + line-height: 1; + color: var(--bs-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: var(--bs-badge-border-radius); +} +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.alert { + --bs-alert-bg: transparent; + --bs-alert-padding-x: 1rem; + --bs-alert-padding-y: 1rem; + --bs-alert-margin-bottom: 1rem; + --bs-alert-color: inherit; + --bs-alert-border-color: transparent; + --bs-alert-border: 1px solid var(--bs-alert-border-color); + --bs-alert-border-radius: 0.375rem; + position: relative; + padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x); + margin-bottom: var(--bs-alert-margin-bottom); + color: var(--bs-alert-color); + background-color: var(--bs-alert-bg); + border: var(--bs-alert-border); + border-radius: var(--bs-alert-border-radius); +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 3rem; +} +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem; +} + +.alert-primary { + --bs-alert-color: #084298; + --bs-alert-bg: #cfe2ff; + --bs-alert-border-color: #b6d4fe; +} +.alert-primary .alert-link { + color: #06357a; +} + +.alert-secondary { + --bs-alert-color: #41464b; + --bs-alert-bg: #e2e3e5; + --bs-alert-border-color: #d3d6d8; +} +.alert-secondary .alert-link { + color: #34383c; +} + +.alert-success { + --bs-alert-color: #0f5132; + --bs-alert-bg: #d1e7dd; + --bs-alert-border-color: #badbcc; +} +.alert-success .alert-link { + color: #0c4128; +} + +.alert-info { + --bs-alert-color: #055160; + --bs-alert-bg: #cff4fc; + --bs-alert-border-color: #b6effb; +} +.alert-info .alert-link { + color: #04414d; +} + +.alert-warning { + --bs-alert-color: #664d03; + --bs-alert-bg: #fff3cd; + --bs-alert-border-color: #ffecb5; +} +.alert-warning .alert-link { + color: #523e02; +} + +.alert-danger { + --bs-alert-color: #842029; + --bs-alert-bg: #f8d7da; + --bs-alert-border-color: #f5c2c7; +} +.alert-danger .alert-link { + color: #6a1a21; +} + +.alert-light { + --bs-alert-color: #636464; + --bs-alert-bg: #fefefe; + --bs-alert-border-color: #fdfdfe; +} +.alert-light .alert-link { + color: #4f5050; +} + +.alert-dark { + --bs-alert-color: #141619; + --bs-alert-bg: #d3d3d4; + --bs-alert-border-color: #bcbebf; +} +.alert-dark .alert-link { + color: #101214; +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem; + } +} +.progress { + --bs-progress-height: 1rem; + --bs-progress-font-size: 0.75rem; + --bs-progress-bg: #e9ecef; + --bs-progress-border-radius: 0.375rem; + --bs-progress-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); + --bs-progress-bar-color: #fff; + --bs-progress-bar-bg: #0d6efd; + --bs-progress-bar-transition: width 0.6s ease; + display: flex; + height: var(--bs-progress-height); + overflow: hidden; + font-size: var(--bs-progress-font-size); + background-color: var(--bs-progress-bg); + border-radius: var(--bs-progress-border-radius); +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: var(--bs-progress-bar-color); + text-align: center; + white-space: nowrap; + background-color: var(--bs-progress-bar-bg); + transition: var(--bs-progress-bar-transition); +} +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none; + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: var(--bs-progress-height) var(--bs-progress-height); +} + +.progress-bar-animated { + animation: 1s linear infinite progress-bar-stripes; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + animation: none; + } +} + +.list-group { + --bs-list-group-color: #212529; + --bs-list-group-bg: #fff; + --bs-list-group-border-color: rgba(0, 0, 0, 0.125); + --bs-list-group-border-width: 1px; + --bs-list-group-border-radius: 0.375rem; + --bs-list-group-item-padding-x: 1rem; + --bs-list-group-item-padding-y: 0.5rem; + --bs-list-group-action-color: #495057; + --bs-list-group-action-hover-color: #495057; + --bs-list-group-action-hover-bg: #f8f9fa; + --bs-list-group-action-active-color: #212529; + --bs-list-group-action-active-bg: #e9ecef; + --bs-list-group-disabled-color: #6c757d; + --bs-list-group-disabled-bg: #fff; + --bs-list-group-active-color: #fff; + --bs-list-group-active-bg: #0d6efd; + --bs-list-group-active-border-color: #0d6efd; + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: var(--bs-list-group-border-radius); +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section; +} +.list-group-numbered > .list-group-item::before { + content: counters(section, ".") ". "; + counter-increment: section; +} + +.list-group-item-action { + width: 100%; + color: var(--bs-list-group-action-color); + text-align: inherit; +} +.list-group-item-action:hover, .list-group-item-action:focus { + z-index: 1; + color: var(--bs-list-group-action-hover-color); + text-decoration: none; + background-color: var(--bs-list-group-action-hover-bg); +} +.list-group-item-action:active { + color: var(--bs-list-group-action-active-color); + background-color: var(--bs-list-group-action-active-bg); +} + +.list-group-item { + position: relative; + display: block; + padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x); + color: var(--bs-list-group-color); + text-decoration: none; + background-color: var(--bs-list-group-bg); + border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color); +} +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; +} +.list-group-item.disabled, .list-group-item:disabled { + color: var(--bs-list-group-disabled-color); + pointer-events: none; + background-color: var(--bs-list-group-disabled-bg); +} +.list-group-item.active { + z-index: 2; + color: var(--bs-list-group-active-color); + background-color: var(--bs-list-group-active-bg); + border-color: var(--bs-list-group-active-border-color); +} +.list-group-item + .list-group-item { + border-top-width: 0; +} +.list-group-item + .list-group-item.active { + margin-top: calc(-1 * var(--bs-list-group-border-width)); + border-top-width: var(--bs-list-group-border-width); +} + +.list-group-horizontal { + flex-direction: row; +} +.list-group-horizontal > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; +} +.list-group-horizontal > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; +} +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row; + } + .list-group-horizontal-sm > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-sm > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row; + } + .list-group-horizontal-md > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-md > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row; + } + .list-group-horizontal-lg > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-lg > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction: row; + } + .list-group-horizontal-xl > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-xl > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row; + } + .list-group-horizontal-xxl > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +.list-group-flush { + border-radius: 0; +} +.list-group-flush > .list-group-item { + border-width: 0 0 var(--bs-list-group-border-width); +} +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; +} + +.list-group-item-primary { + color: #084298; + background-color: #cfe2ff; +} +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #084298; + background-color: #bacbe6; +} +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #084298; + border-color: #084298; +} + +.list-group-item-secondary { + color: #41464b; + background-color: #e2e3e5; +} +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #41464b; + background-color: #cbccce; +} +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #41464b; + border-color: #41464b; +} + +.list-group-item-success { + color: #0f5132; + background-color: #d1e7dd; +} +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #0f5132; + background-color: #bcd0c7; +} +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0f5132; + border-color: #0f5132; +} + +.list-group-item-info { + color: #055160; + background-color: #cff4fc; +} +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #055160; + background-color: #badce3; +} +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #055160; + border-color: #055160; +} + +.list-group-item-warning { + color: #664d03; + background-color: #fff3cd; +} +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #664d03; + background-color: #e6dbb9; +} +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #664d03; + border-color: #664d03; +} + +.list-group-item-danger { + color: #842029; + background-color: #f8d7da; +} +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #842029; + background-color: #dfc2c4; +} +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842029; + border-color: #842029; +} + +.list-group-item-light { + color: #636464; + background-color: #fefefe; +} +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #636464; + background-color: #e5e5e5; +} +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #636464; + border-color: #636464; +} + +.list-group-item-dark { + color: #141619; + background-color: #d3d3d4; +} +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #141619; + background-color: #bebebf; +} +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #141619; + border-color: #141619; +} + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: 0.25em 0.25em; + color: #000; + background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat; + border: 0; + border-radius: 0.375rem; + opacity: 0.5; +} +.btn-close:hover { + color: #000; + text-decoration: none; + opacity: 0.75; +} +.btn-close:focus { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + opacity: 1; +} +.btn-close:disabled, .btn-close.disabled { + pointer-events: none; + user-select: none; + opacity: 0.25; +} + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%); +} + +.toast { + --bs-toast-zindex: 1090; + --bs-toast-padding-x: 0.75rem; + --bs-toast-padding-y: 0.5rem; + --bs-toast-spacing: 1.5rem; + --bs-toast-max-width: 350px; + --bs-toast-font-size: 0.875rem; + --bs-toast-color: ; + --bs-toast-bg: rgba(255, 255, 255, 0.85); + --bs-toast-border-width: 1px; + --bs-toast-border-color: var(--bs-border-color-translucent); + --bs-toast-border-radius: 0.375rem; + --bs-toast-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-toast-header-color: #6c757d; + --bs-toast-header-bg: rgba(255, 255, 255, 0.85); + --bs-toast-header-border-color: rgba(0, 0, 0, 0.05); + width: var(--bs-toast-max-width); + max-width: 100%; + font-size: var(--bs-toast-font-size); + color: var(--bs-toast-color); + pointer-events: auto; + background-color: var(--bs-toast-bg); + background-clip: padding-box; + border: var(--bs-toast-border-width) solid var(--bs-toast-border-color); + box-shadow: var(--bs-toast-box-shadow); + border-radius: var(--bs-toast-border-radius); +} +.toast.showing { + opacity: 0; +} +.toast:not(.show) { + display: none; +} + +.toast-container { + --bs-toast-zindex: 1090; + position: absolute; + z-index: var(--bs-toast-zindex); + width: max-content; + max-width: 100%; + pointer-events: none; +} +.toast-container > :not(:last-child) { + margin-bottom: var(--bs-toast-spacing); +} + +.toast-header { + display: flex; + align-items: center; + padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x); + color: var(--bs-toast-header-color); + background-color: var(--bs-toast-header-bg); + background-clip: padding-box; + border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color); + border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)); + border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)); +} +.toast-header .btn-close { + margin-right: calc(-0.5 * var(--bs-toast-padding-x)); + margin-left: var(--bs-toast-padding-x); +} + +.toast-body { + padding: var(--bs-toast-padding-x); + word-wrap: break-word; +} + +.modal { + --bs-modal-zindex: 1055; + --bs-modal-width: 500px; + --bs-modal-padding: 1rem; + --bs-modal-margin: 0.5rem; + --bs-modal-color: ; + --bs-modal-bg: #fff; + --bs-modal-border-color: var(--bs-border-color-translucent); + --bs-modal-border-width: 1px; + --bs-modal-border-radius: 0.5rem; + --bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); + --bs-modal-inner-border-radius: calc(0.5rem - 1px); + --bs-modal-header-padding-x: 1rem; + --bs-modal-header-padding-y: 1rem; + --bs-modal-header-padding: 1rem 1rem; + --bs-modal-header-border-color: var(--bs-border-color); + --bs-modal-header-border-width: 1px; + --bs-modal-title-line-height: 1.5; + --bs-modal-footer-gap: 0.5rem; + --bs-modal-footer-bg: ; + --bs-modal-footer-border-color: var(--bs-border-color); + --bs-modal-footer-border-width: 1px; + position: fixed; + top: 0; + left: 0; + z-index: var(--bs-modal-zindex); + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0; +} + +.modal-dialog { + position: relative; + width: auto; + margin: var(--bs-modal-margin); + pointer-events: none; +} +.modal.fade .modal-dialog { + transition: transform 0.3s ease-out; + transform: translate(0, -50px); +} +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none; + } +} +.modal.show .modal-dialog { + transform: none; +} +.modal.modal-static .modal-dialog { + transform: scale(1.02); +} + +.modal-dialog-scrollable { + height: calc(100% - var(--bs-modal-margin) * 2); +} +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden; +} +.modal-dialog-scrollable .modal-body { + overflow-y: auto; +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - var(--bs-modal-margin) * 2); +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + color: var(--bs-modal-color); + pointer-events: auto; + background-color: var(--bs-modal-bg); + background-clip: padding-box; + border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); + border-radius: var(--bs-modal-border-radius); + outline: 0; +} + +.modal-backdrop { + --bs-backdrop-zindex: 1050; + --bs-backdrop-bg: #000; + --bs-backdrop-opacity: 0.5; + position: fixed; + top: 0; + left: 0; + z-index: var(--bs-backdrop-zindex); + width: 100vw; + height: 100vh; + background-color: var(--bs-backdrop-bg); +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: var(--bs-backdrop-opacity); +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: var(--bs-modal-header-padding); + border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color); + border-top-left-radius: var(--bs-modal-inner-border-radius); + border-top-right-radius: var(--bs-modal-inner-border-radius); +} +.modal-header .btn-close { + padding: calc(var(--bs-modal-header-padding-y) * 0.5) calc(var(--bs-modal-header-padding-x) * 0.5); + margin: calc(-0.5 * var(--bs-modal-header-padding-y)) calc(-0.5 * var(--bs-modal-header-padding-x)) calc(-0.5 * var(--bs-modal-header-padding-y)) auto; +} + +.modal-title { + margin-bottom: 0; + line-height: var(--bs-modal-title-line-height); +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: var(--bs-modal-padding); +} + +.modal-footer { + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + align-items: center; + justify-content: flex-end; + padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * 0.5); + background-color: var(--bs-modal-footer-bg); + border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color); + border-bottom-right-radius: var(--bs-modal-inner-border-radius); + border-bottom-left-radius: var(--bs-modal-inner-border-radius); +} +.modal-footer > * { + margin: calc(var(--bs-modal-footer-gap) * 0.5); +} + +@media (min-width: 576px) { + .modal { + --bs-modal-margin: 1.75rem; + --bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + } + .modal-dialog { + max-width: var(--bs-modal-width); + margin-right: auto; + margin-left: auto; + } + .modal-sm { + --bs-modal-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg, + .modal-xl { + --bs-modal-width: 800px; + } +} +@media (min-width: 1200px) { + .modal-xl { + --bs-modal-width: 1140px; + } +} +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; +} +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0; +} +.modal-fullscreen .modal-header, +.modal-fullscreen .modal-footer { + border-radius: 0; +} +.modal-fullscreen .modal-body { + overflow-y: auto; +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-header, + .modal-fullscreen-sm-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-md-down .modal-header, + .modal-fullscreen-md-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-md-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-header, + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-header, + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-header, + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto; + } +} +.tooltip { + --bs-tooltip-zindex: 1080; + --bs-tooltip-max-width: 200px; + --bs-tooltip-padding-x: 0.5rem; + --bs-tooltip-padding-y: 0.25rem; + --bs-tooltip-margin: ; + --bs-tooltip-font-size: 0.875rem; + --bs-tooltip-color: #fff; + --bs-tooltip-bg: #000; + --bs-tooltip-border-radius: 0.375rem; + --bs-tooltip-opacity: 0.9; + --bs-tooltip-arrow-width: 0.8rem; + --bs-tooltip-arrow-height: 0.4rem; + z-index: var(--bs-tooltip-zindex); + display: block; + padding: var(--bs-tooltip-arrow-height); + margin: var(--bs-tooltip-margin); + font-family: var(--bs-font-sans-serif); + 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; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--bs-tooltip-font-size); + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: var(--bs-tooltip-opacity); +} +.tooltip .tooltip-arrow { + display: block; + width: var(--bs-tooltip-arrow-width); + height: var(--bs-tooltip-arrow-height); +} +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow { + bottom: 0; +} +.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before { + top: -1px; + border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0; + border-top-color: var(--bs-tooltip-bg); +} + +/* rtl:begin:ignore */ +.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow { + left: 0; + width: var(--bs-tooltip-arrow-height); + height: var(--bs-tooltip-arrow-width); +} +.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before { + right: -1px; + border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0; + border-right-color: var(--bs-tooltip-bg); +} + +/* rtl:end:ignore */ +.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow { + top: 0; +} +.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before { + bottom: -1px; + border-width: 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height); + border-bottom-color: var(--bs-tooltip-bg); +} + +/* rtl:begin:ignore */ +.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow { + right: 0; + width: var(--bs-tooltip-arrow-height); + height: var(--bs-tooltip-arrow-width); +} +.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before { + left: -1px; + border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height); + border-left-color: var(--bs-tooltip-bg); +} + +/* rtl:end:ignore */ +.tooltip-inner { + max-width: var(--bs-tooltip-max-width); + padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x); + color: var(--bs-tooltip-color); + text-align: center; + background-color: var(--bs-tooltip-bg); + border-radius: var(--bs-tooltip-border-radius); +} + +.popover { + --bs-popover-zindex: 1070; + --bs-popover-max-width: 276px; + --bs-popover-font-size: 0.875rem; + --bs-popover-bg: #fff; + --bs-popover-border-width: 1px; + --bs-popover-border-color: var(--bs-border-color-translucent); + --bs-popover-border-radius: 0.5rem; + --bs-popover-inner-border-radius: calc(0.5rem - 1px); + --bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-popover-header-padding-x: 1rem; + --bs-popover-header-padding-y: 0.5rem; + --bs-popover-header-font-size: 1rem; + --bs-popover-header-color: ; + --bs-popover-header-bg: #f0f0f0; + --bs-popover-body-padding-x: 1rem; + --bs-popover-body-padding-y: 1rem; + --bs-popover-body-color: #212529; + --bs-popover-arrow-width: 1rem; + --bs-popover-arrow-height: 0.5rem; + --bs-popover-arrow-border: var(--bs-popover-border-color); + z-index: var(--bs-popover-zindex); + display: block; + max-width: var(--bs-popover-max-width); + font-family: var(--bs-font-sans-serif); + 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; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--bs-popover-font-size); + word-wrap: break-word; + background-color: var(--bs-popover-bg); + background-clip: padding-box; + border: var(--bs-popover-border-width) solid var(--bs-popover-border-color); + border-radius: var(--bs-popover-border-radius); +} +.popover .popover-arrow { + display: block; + width: var(--bs-popover-arrow-width); + height: var(--bs-popover-arrow-height); +} +.popover .popover-arrow::before, .popover .popover-arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; + border-width: 0; +} + +.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow { + bottom: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); +} +.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { + border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0; +} +.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before { + bottom: 0; + border-top-color: var(--bs-popover-arrow-border); +} +.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { + bottom: var(--bs-popover-border-width); + border-top-color: var(--bs-popover-bg); +} + +/* rtl:begin:ignore */ +.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow { + left: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); + width: var(--bs-popover-arrow-height); + height: var(--bs-popover-arrow-width); +} +.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { + border-width: calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0; +} +.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before { + left: 0; + border-right-color: var(--bs-popover-arrow-border); +} +.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { + left: var(--bs-popover-border-width); + border-right-color: var(--bs-popover-bg); +} + +/* rtl:end:ignore */ +.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow { + top: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); +} +.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { + border-width: 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height); +} +.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before { + top: 0; + border-bottom-color: var(--bs-popover-arrow-border); +} +.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { + top: var(--bs-popover-border-width); + border-bottom-color: var(--bs-popover-bg); +} +.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: var(--bs-popover-arrow-width); + margin-left: calc(-0.5 * var(--bs-popover-arrow-width)); + content: ""; + border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg); +} + +/* rtl:begin:ignore */ +.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow { + right: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); + width: var(--bs-popover-arrow-height); + height: var(--bs-popover-arrow-width); +} +.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { + border-width: calc(var(--bs-popover-arrow-width) * 0.5) 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height); +} +.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before { + right: 0; + border-left-color: var(--bs-popover-arrow-border); +} +.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { + right: var(--bs-popover-border-width); + border-left-color: var(--bs-popover-bg); +} + +/* rtl:end:ignore */ +.popover-header { + padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x); + margin-bottom: 0; + font-size: var(--bs-popover-header-font-size); + color: var(--bs-popover-header-color); + background-color: var(--bs-popover-header-bg); + border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color); + border-top-left-radius: var(--bs-popover-inner-border-radius); + border-top-right-radius: var(--bs-popover-inner-border-radius); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x); + color: var(--bs-popover-body-color); +} + +.carousel { + position: relative; +} + +.carousel.pointer-event { + 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%; + backface-visibility: hidden; + transition: transform 0.6s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none; + } +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next:not(.carousel-item-start), +.active.carousel-item-end { + transform: translateX(100%); +} + +.carousel-item-prev:not(.carousel-item-end), +.active.carousel-item-start { + transform: translateX(-100%); +} + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none; +} +.carousel-fade .carousel-item.active, +.carousel-fade .carousel-item-next.carousel-item-start, +.carousel-fade .carousel-item-prev.carousel-item-end { + z-index: 1; + opacity: 1; +} +.carousel-fade .active.carousel-item-start, +.carousel-fade .active.carousel-item-end { + z-index: 0; + opacity: 0; + transition: opacity 0s 0.6s; +} +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-start, + .carousel-fade .active.carousel-item-end { + transition: none; + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: none; + border: 0; + opacity: 0.5; + transition: opacity 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-control-prev, + .carousel-control-next { + transition: none; + } +} +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: 0.9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100%; +} + +/* rtl:options: { + "autoRename": true, + "stringMap":[ { + "name" : "prev-next", + "search" : "prev", + "replace" : "next" + } ] +} */ +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; + list-style: none; +} +.carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: 0.5; + transition: opacity 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-indicators [data-bs-target] { + transition: none; + } +} +.carousel-indicators .active { + opacity: 1; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center; +} + +.carousel-dark .carousel-control-prev-icon, +.carousel-dark .carousel-control-next-icon { + filter: invert(1) grayscale(100); +} +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000; +} +.carousel-dark .carousel-caption { + color: #000; +} + +.spinner-grow, +.spinner-border { + display: inline-block; + width: var(--bs-spinner-width); + height: var(--bs-spinner-height); + vertical-align: var(--bs-spinner-vertical-align); + border-radius: 50%; + animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name); +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) /* rtl:ignore */; + } +} +.spinner-border { + --bs-spinner-width: 2rem; + --bs-spinner-height: 2rem; + --bs-spinner-vertical-align: -0.125em; + --bs-spinner-border-width: 0.25em; + --bs-spinner-animation-speed: 0.75s; + --bs-spinner-animation-name: spinner-border; + border: var(--bs-spinner-border-width) solid currentcolor; + border-right-color: transparent; +} + +.spinner-border-sm { + --bs-spinner-width: 1rem; + --bs-spinner-height: 1rem; + --bs-spinner-border-width: 0.2em; +} + +@keyframes spinner-grow { + 0% { + transform: scale(0); + } + 50% { + opacity: 1; + transform: none; + } +} +.spinner-grow { + --bs-spinner-width: 2rem; + --bs-spinner-height: 2rem; + --bs-spinner-vertical-align: -0.125em; + --bs-spinner-animation-speed: 0.75s; + --bs-spinner-animation-name: spinner-grow; + background-color: currentcolor; + opacity: 0; +} + +.spinner-grow-sm { + --bs-spinner-width: 1rem; + --bs-spinner-height: 1rem; +} + +@media (prefers-reduced-motion: reduce) { + .spinner-border, + .spinner-grow { + --bs-spinner-animation-speed: 1.5s; + } +} +.offcanvas, .offcanvas-xxl, .offcanvas-xl, .offcanvas-lg, .offcanvas-md, .offcanvas-sm { + --bs-offcanvas-zindex: 1045; + --bs-offcanvas-width: 400px; + --bs-offcanvas-height: 30vh; + --bs-offcanvas-padding-x: 1rem; + --bs-offcanvas-padding-y: 1rem; + --bs-offcanvas-color: ; + --bs-offcanvas-bg: #fff; + --bs-offcanvas-border-width: 1px; + --bs-offcanvas-border-color: var(--bs-border-color-translucent); + --bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); +} + +@media (max-width: 575.98px) { + .offcanvas-sm { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; + } +} +@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-sm { + transition: none; + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.showing, .offcanvas-sm.show:not(.hiding) { + transform: none; + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.showing, .offcanvas-sm.hiding, .offcanvas-sm.show { + visibility: visible; + } +} +@media (min-width: 576px) { + .offcanvas-sm { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-sm .offcanvas-header { + display: none; + } + .offcanvas-sm .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 767.98px) { + .offcanvas-md { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; + } +} +@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-md { + transition: none; + } +} +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } +} +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } +} +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } +} +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } +} +@media (max-width: 767.98px) { + .offcanvas-md.showing, .offcanvas-md.show:not(.hiding) { + transform: none; + } +} +@media (max-width: 767.98px) { + .offcanvas-md.showing, .offcanvas-md.hiding, .offcanvas-md.show { + visibility: visible; + } +} +@media (min-width: 768px) { + .offcanvas-md { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-md .offcanvas-header { + display: none; + } + .offcanvas-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; + } +} +@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-lg { + transition: none; + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.showing, .offcanvas-lg.show:not(.hiding) { + transform: none; + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.showing, .offcanvas-lg.hiding, .offcanvas-lg.show { + visibility: visible; + } +} +@media (min-width: 992px) { + .offcanvas-lg { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-lg .offcanvas-header { + display: none; + } + .offcanvas-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; + } +} +@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-xl { + transition: none; + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.showing, .offcanvas-xl.show:not(.hiding) { + transform: none; + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.showing, .offcanvas-xl.hiding, .offcanvas-xl.show { + visibility: visible; + } +} +@media (min-width: 1200px) { + .offcanvas-xl { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-xl .offcanvas-header { + display: none; + } + .offcanvas-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; + } +} +@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-xxl { + transition: none; + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.showing, .offcanvas-xxl.show:not(.hiding) { + transform: none; + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.showing, .offcanvas-xxl.hiding, .offcanvas-xxl.show { + visibility: visible; + } +} +@media (min-width: 1400px) { + .offcanvas-xxl { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-xxl .offcanvas-header { + display: none; + } + .offcanvas-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +.offcanvas { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + transition: transform 0.3s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .offcanvas { + transition: none; + } +} +.offcanvas.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); +} +.offcanvas.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); +} +.offcanvas.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); +} +.offcanvas.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); +} +.offcanvas.showing, .offcanvas.show:not(.hiding) { + transform: none; +} +.offcanvas.showing, .offcanvas.hiding, .offcanvas.show { + visibility: visible; +} + +.offcanvas-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; +} +.offcanvas-backdrop.fade { + opacity: 0; +} +.offcanvas-backdrop.show { + opacity: 0.5; +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x); +} +.offcanvas-header .btn-close { + padding: calc(var(--bs-offcanvas-padding-y) * 0.5) calc(var(--bs-offcanvas-padding-x) * 0.5); + margin-top: calc(-0.5 * var(--bs-offcanvas-padding-y)); + margin-right: calc(-0.5 * var(--bs-offcanvas-padding-x)); + margin-bottom: calc(-0.5 * var(--bs-offcanvas-padding-y)); +} + +.offcanvas-title { + margin-bottom: 0; + line-height: 1.5; +} + +.offcanvas-body { + flex-grow: 1; + padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x); + overflow-y: auto; +} + +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentcolor; + opacity: 0.5; +} +.placeholder.btn::before { + display: inline-block; + content: ""; +} + +.placeholder-xs { + min-height: 0.6em; +} + +.placeholder-sm { + min-height: 0.8em; +} + +.placeholder-lg { + min-height: 1.2em; +} + +.placeholder-glow .placeholder { + animation: placeholder-glow 2s ease-in-out infinite; +} + +@keyframes placeholder-glow { + 50% { + opacity: 0.2; + } +} +.placeholder-wave { + mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + mask-size: 200% 100%; + animation: placeholder-wave 2s linear infinite; +} + +@keyframes placeholder-wave { + 100% { + mask-position: -200% 0%; + } +} +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.text-bg-primary { + color: #fff !important; + background-color: RGBA(13, 110, 253, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-secondary { + color: #fff !important; + background-color: RGBA(108, 117, 125, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-success { + color: #fff !important; + background-color: RGBA(25, 135, 84, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-info { + color: #000 !important; + background-color: RGBA(13, 202, 240, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-warning { + color: #000 !important; + background-color: RGBA(255, 193, 7, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-danger { + color: #fff !important; + background-color: RGBA(220, 53, 69, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-light { + color: #000 !important; + background-color: RGBA(248, 249, 250, var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-dark { + color: #fff !important; + background-color: RGBA(33, 37, 41, var(--bs-bg-opacity, 1)) !important; +} + +.link-primary { + color: #0d6efd !important; +} +.link-primary:hover, .link-primary:focus { + color: #0a58ca !important; +} + +.link-secondary { + color: #6c757d !important; +} +.link-secondary:hover, .link-secondary:focus { + color: #565e64 !important; +} + +.link-success { + color: #198754 !important; +} +.link-success:hover, .link-success:focus { + color: #146c43 !important; +} + +.link-info { + color: #0dcaf0 !important; +} +.link-info:hover, .link-info:focus { + color: #3dd5f3 !important; +} + +.link-warning { + color: #ffc107 !important; +} +.link-warning:hover, .link-warning:focus { + color: #ffcd39 !important; +} + +.link-danger { + color: #dc3545 !important; +} +.link-danger:hover, .link-danger:focus { + color: #b02a37 !important; +} + +.link-light { + color: #f8f9fa !important; +} +.link-light:hover, .link-light:focus { + color: #f9fafb !important; +} + +.link-dark { + color: #212529 !important; +} +.link-dark:hover, .link-dark:focus { + color: #1a1e21 !important; +} + +.ratio { + position: relative; + width: 100%; +} +.ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: ""; +} +.ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.ratio-1x1 { + --bs-aspect-ratio: 100%; +} + +.ratio-4x3 { + --bs-aspect-ratio: 75%; +} + +.ratio-16x9 { + --bs-aspect-ratio: 56.25%; +} + +.ratio-21x9 { + --bs-aspect-ratio: 42.8571428571%; +} + +.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; +} + +.sticky-top { + position: sticky; + top: 0; + z-index: 1020; +} + +.sticky-bottom { + position: sticky; + bottom: 0; + z-index: 1020; +} + +@media (min-width: 576px) { + .sticky-sm-top { + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-sm-bottom { + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 768px) { + .sticky-md-top { + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-md-bottom { + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 992px) { + .sticky-lg-top { + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-lg-bottom { + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 1200px) { + .sticky-xl-top { + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-xl-bottom { + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 1400px) { + .sticky-xxl-top { + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-xxl-bottom { + position: sticky; + bottom: 0; + z-index: 1020; + } +} +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch; +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch; +} + +.visually-hidden, +.visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: ""; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentcolor; + opacity: 0.25; +} + +.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; +} + +.float-start { + float: left !important; +} + +.float-end { + float: right !important; +} + +.float-none { + float: none !important; +} + +.opacity-0 { + opacity: 0 !important; +} + +.opacity-25 { + opacity: 0.25 !important; +} + +.opacity-50 { + opacity: 0.5 !important; +} + +.opacity-75 { + opacity: 0.75 !important; +} + +.opacity-100 { + opacity: 1 !important; +} + +.overflow-auto { + overflow: auto !important; +} + +.overflow-hidden { + overflow: hidden !important; +} + +.overflow-visible { + overflow: visible !important; +} + +.overflow-scroll { + overflow: scroll !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.shadow { + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; +} + +.shadow-sm { + box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important; +} + +.shadow-none { + box-shadow: none !important; +} + +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: sticky !important; +} + +.top-0 { + top: 0 !important; +} + +.top-50 { + top: 50% !important; +} + +.top-100 { + top: 100% !important; +} + +.bottom-0 { + bottom: 0 !important; +} + +.bottom-50 { + bottom: 50% !important; +} + +.bottom-100 { + bottom: 100% !important; +} + +.start-0 { + left: 0 !important; +} + +.start-50 { + left: 50% !important; +} + +.start-100 { + left: 100% !important; +} + +.end-0 { + right: 0 !important; +} + +.end-50 { + right: 50% !important; +} + +.end-100 { + right: 100% !important; +} + +.translate-middle { + transform: translate(-50%, -50%) !important; +} + +.translate-middle-x { + transform: translateX(-50%) !important; +} + +.translate-middle-y { + transform: translateY(-50%) !important; +} + +.border { + border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top { + border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-end { + border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-end-0 { + border-right: 0 !important; +} + +.border-bottom { + border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-start { + border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-start-0 { + border-left: 0 !important; +} + +.border-primary { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important; +} + +.border-secondary { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important; +} + +.border-success { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important; +} + +.border-info { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important; +} + +.border-warning { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important; +} + +.border-danger { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important; +} + +.border-light { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important; +} + +.border-dark { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important; +} + +.border-white { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important; +} + +.border-1 { + --bs-border-width: 1px; +} + +.border-2 { + --bs-border-width: 2px; +} + +.border-3 { + --bs-border-width: 3px; +} + +.border-4 { + --bs-border-width: 4px; +} + +.border-5 { + --bs-border-width: 5px; +} + +.border-opacity-10 { + --bs-border-opacity: 0.1; +} + +.border-opacity-25 { + --bs-border-opacity: 0.25; +} + +.border-opacity-50 { + --bs-border-opacity: 0.5; +} + +.border-opacity-75 { + --bs-border-opacity: 0.75; +} + +.border-opacity-100 { + --bs-border-opacity: 1; +} + +.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; +} + +.mw-100 { + max-width: 100% !important; +} + +.vw-100 { + width: 100vw !important; +} + +.min-vw-100 { + min-width: 100vw !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; +} + +.mh-100 { + max-height: 100% !important; +} + +.vh-100 { + height: 100vh !important; +} + +.min-vh-100 { + min-height: 100vh !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} + +.gap-0 { + gap: 0 !important; +} + +.gap-1 { + gap: 0.25rem !important; +} + +.gap-2 { + gap: 0.5rem !important; +} + +.gap-3 { + gap: 1rem !important; +} + +.gap-4 { + gap: 1.5rem !important; +} + +.gap-5 { + gap: 3rem !important; +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important; +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw) !important; +} + +.fs-2 { + font-size: calc(1.325rem + 0.9vw) !important; +} + +.fs-3 { + font-size: calc(1.3rem + 0.6vw) !important; +} + +.fs-4 { + font-size: calc(1.275rem + 0.3vw) !important; +} + +.fs-5 { + font-size: 1.25rem !important; +} + +.fs-6 { + font-size: 1rem !important; +} + +.fst-italic { + font-style: italic !important; +} + +.fst-normal { + font-style: normal !important; +} + +.fw-light { + font-weight: 300 !important; +} + +.fw-lighter { + font-weight: lighter !important; +} + +.fw-normal { + font-weight: 400 !important; +} + +.fw-bold { + font-weight: 700 !important; +} + +.fw-semibold { + font-weight: 600 !important; +} + +.fw-bolder { + font-weight: bolder !important; +} + +.lh-1 { + line-height: 1 !important; +} + +.lh-sm { + line-height: 1.25 !important; +} + +.lh-base { + line-height: 1.5 !important; +} + +.lh-lg { + line-height: 2 !important; +} + +.text-start { + text-align: left !important; +} + +.text-end { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +.text-decoration-none { + text-decoration: none !important; +} + +.text-decoration-underline { + text-decoration: underline !important; +} + +.text-decoration-line-through { + text-decoration: line-through !important; +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.text-wrap { + white-space: normal !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +/* rtl:begin:remove */ +.text-break { + word-wrap: break-word !important; + word-break: break-word !important; +} + +/* rtl:end:remove */ +.text-primary { + --bs-text-opacity: 1; + color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important; +} + +.text-secondary { + --bs-text-opacity: 1; + color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important; +} + +.text-success { + --bs-text-opacity: 1; + color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important; +} + +.text-info { + --bs-text-opacity: 1; + color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important; +} + +.text-warning { + --bs-text-opacity: 1; + color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important; +} + +.text-danger { + --bs-text-opacity: 1; + color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important; +} + +.text-light { + --bs-text-opacity: 1; + color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important; +} + +.text-dark { + --bs-text-opacity: 1; + color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important; +} + +.text-black { + --bs-text-opacity: 1; + color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important; +} + +.text-white { + --bs-text-opacity: 1; + color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important; +} + +.text-body { + --bs-text-opacity: 1; + color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important; +} + +.text-muted { + --bs-text-opacity: 1; + color: #6c757d !important; +} + +.text-black-50 { + --bs-text-opacity: 1; + color: rgba(0, 0, 0, 0.5) !important; +} + +.text-white-50 { + --bs-text-opacity: 1; + color: rgba(255, 255, 255, 0.5) !important; +} + +.text-reset { + --bs-text-opacity: 1; + color: inherit !important; +} + +.text-opacity-25 { + --bs-text-opacity: 0.25; +} + +.text-opacity-50 { + --bs-text-opacity: 0.5; +} + +.text-opacity-75 { + --bs-text-opacity: 0.75; +} + +.text-opacity-100 { + --bs-text-opacity: 1; +} + +.bg-primary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-secondary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-success { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-info { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-warning { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-danger { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-light { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-dark { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-black { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-white { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-body { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-transparent { + --bs-bg-opacity: 1; + background-color: transparent !important; +} + +.bg-opacity-10 { + --bs-bg-opacity: 0.1; +} + +.bg-opacity-25 { + --bs-bg-opacity: 0.25; +} + +.bg-opacity-50 { + --bs-bg-opacity: 0.5; +} + +.bg-opacity-75 { + --bs-bg-opacity: 0.75; +} + +.bg-opacity-100 { + --bs-bg-opacity: 1; +} + +.bg-gradient { + background-image: var(--bs-gradient) !important; +} + +.user-select-all { + user-select: all !important; +} + +.user-select-auto { + user-select: auto !important; +} + +.user-select-none { + user-select: none !important; +} + +.pe-none { + pointer-events: none !important; +} + +.pe-auto { + pointer-events: auto !important; +} + +.rounded { + border-radius: var(--bs-border-radius) !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.rounded-1 { + border-radius: var(--bs-border-radius-sm) !important; +} + +.rounded-2 { + border-radius: var(--bs-border-radius) !important; +} + +.rounded-3 { + border-radius: var(--bs-border-radius-lg) !important; +} + +.rounded-4 { + border-radius: var(--bs-border-radius-xl) !important; +} + +.rounded-5 { + border-radius: var(--bs-border-radius-2xl) !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: var(--bs-border-radius-pill) !important; +} + +.rounded-top { + border-top-left-radius: var(--bs-border-radius) !important; + border-top-right-radius: var(--bs-border-radius) !important; +} + +.rounded-end { + border-top-right-radius: var(--bs-border-radius) !important; + border-bottom-right-radius: var(--bs-border-radius) !important; +} + +.rounded-bottom { + border-bottom-right-radius: var(--bs-border-radius) !important; + border-bottom-left-radius: var(--bs-border-radius) !important; +} + +.rounded-start { + border-bottom-left-radius: var(--bs-border-radius) !important; + border-top-left-radius: var(--bs-border-radius) !important; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +@media (min-width: 576px) { + .float-sm-start { + float: left !important; + } + .float-sm-end { + float: right !important; + } + .float-sm-none { + float: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-grid { + display: grid !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: flex !important; + } + .d-sm-inline-flex { + display: inline-flex !important; + } + .d-sm-none { + display: none !important; + } + .flex-sm-fill { + flex: 1 1 auto !important; + } + .flex-sm-row { + flex-direction: row !important; + } + .flex-sm-column { + flex-direction: column !important; + } + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + .flex-sm-wrap { + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + justify-content: flex-start !important; + } + .justify-content-sm-end { + justify-content: flex-end !important; + } + .justify-content-sm-center { + justify-content: center !important; + } + .justify-content-sm-between { + justify-content: space-between !important; + } + .justify-content-sm-around { + justify-content: space-around !important; + } + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + .align-items-sm-start { + align-items: flex-start !important; + } + .align-items-sm-end { + align-items: flex-end !important; + } + .align-items-sm-center { + align-items: center !important; + } + .align-items-sm-baseline { + align-items: baseline !important; + } + .align-items-sm-stretch { + align-items: stretch !important; + } + .align-content-sm-start { + align-content: flex-start !important; + } + .align-content-sm-end { + align-content: flex-end !important; + } + .align-content-sm-center { + align-content: center !important; + } + .align-content-sm-between { + align-content: space-between !important; + } + .align-content-sm-around { + align-content: space-around !important; + } + .align-content-sm-stretch { + align-content: stretch !important; + } + .align-self-sm-auto { + align-self: auto !important; + } + .align-self-sm-start { + align-self: flex-start !important; + } + .align-self-sm-end { + align-self: flex-end !important; + } + .align-self-sm-center { + align-self: center !important; + } + .align-self-sm-baseline { + align-self: baseline !important; + } + .align-self-sm-stretch { + align-self: stretch !important; + } + .order-sm-first { + order: -1 !important; + } + .order-sm-0 { + order: 0 !important; + } + .order-sm-1 { + order: 1 !important; + } + .order-sm-2 { + order: 2 !important; + } + .order-sm-3 { + order: 3 !important; + } + .order-sm-4 { + order: 4 !important; + } + .order-sm-5 { + order: 5 !important; + } + .order-sm-last { + order: 6 !important; + } + .m-sm-0 { + margin: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-sm-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-sm-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-sm-0 { + margin-top: 0 !important; + } + .mt-sm-1 { + margin-top: 0.25rem !important; + } + .mt-sm-2 { + margin-top: 0.5rem !important; + } + .mt-sm-3 { + margin-top: 1rem !important; + } + .mt-sm-4 { + margin-top: 1.5rem !important; + } + .mt-sm-5 { + margin-top: 3rem !important; + } + .mt-sm-auto { + margin-top: auto !important; + } + .me-sm-0 { + margin-right: 0 !important; + } + .me-sm-1 { + margin-right: 0.25rem !important; + } + .me-sm-2 { + margin-right: 0.5rem !important; + } + .me-sm-3 { + margin-right: 1rem !important; + } + .me-sm-4 { + margin-right: 1.5rem !important; + } + .me-sm-5 { + margin-right: 3rem !important; + } + .me-sm-auto { + margin-right: auto !important; + } + .mb-sm-0 { + margin-bottom: 0 !important; + } + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + .mb-sm-3 { + margin-bottom: 1rem !important; + } + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + .mb-sm-5 { + margin-bottom: 3rem !important; + } + .mb-sm-auto { + margin-bottom: auto !important; + } + .ms-sm-0 { + margin-left: 0 !important; + } + .ms-sm-1 { + margin-left: 0.25rem !important; + } + .ms-sm-2 { + margin-left: 0.5rem !important; + } + .ms-sm-3 { + margin-left: 1rem !important; + } + .ms-sm-4 { + margin-left: 1.5rem !important; + } + .ms-sm-5 { + margin-left: 3rem !important; + } + .ms-sm-auto { + margin-left: auto !important; + } + .p-sm-0 { + padding: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-sm-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-sm-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-sm-0 { + padding-top: 0 !important; + } + .pt-sm-1 { + padding-top: 0.25rem !important; + } + .pt-sm-2 { + padding-top: 0.5rem !important; + } + .pt-sm-3 { + padding-top: 1rem !important; + } + .pt-sm-4 { + padding-top: 1.5rem !important; + } + .pt-sm-5 { + padding-top: 3rem !important; + } + .pe-sm-0 { + padding-right: 0 !important; + } + .pe-sm-1 { + padding-right: 0.25rem !important; + } + .pe-sm-2 { + padding-right: 0.5rem !important; + } + .pe-sm-3 { + padding-right: 1rem !important; + } + .pe-sm-4 { + padding-right: 1.5rem !important; + } + .pe-sm-5 { + padding-right: 3rem !important; + } + .pb-sm-0 { + padding-bottom: 0 !important; + } + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + .pb-sm-3 { + padding-bottom: 1rem !important; + } + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + .pb-sm-5 { + padding-bottom: 3rem !important; + } + .ps-sm-0 { + padding-left: 0 !important; + } + .ps-sm-1 { + padding-left: 0.25rem !important; + } + .ps-sm-2 { + padding-left: 0.5rem !important; + } + .ps-sm-3 { + padding-left: 1rem !important; + } + .ps-sm-4 { + padding-left: 1.5rem !important; + } + .ps-sm-5 { + padding-left: 3rem !important; + } + .gap-sm-0 { + gap: 0 !important; + } + .gap-sm-1 { + gap: 0.25rem !important; + } + .gap-sm-2 { + gap: 0.5rem !important; + } + .gap-sm-3 { + gap: 1rem !important; + } + .gap-sm-4 { + gap: 1.5rem !important; + } + .gap-sm-5 { + gap: 3rem !important; + } + .text-sm-start { + text-align: left !important; + } + .text-sm-end { + text-align: right !important; + } + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .float-md-start { + float: left !important; + } + .float-md-end { + float: right !important; + } + .float-md-none { + float: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-grid { + display: grid !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: flex !important; + } + .d-md-inline-flex { + display: inline-flex !important; + } + .d-md-none { + display: none !important; + } + .flex-md-fill { + flex: 1 1 auto !important; + } + .flex-md-row { + flex-direction: row !important; + } + .flex-md-column { + flex-direction: column !important; + } + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + .flex-md-grow-0 { + flex-grow: 0 !important; + } + .flex-md-grow-1 { + flex-grow: 1 !important; + } + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + .flex-md-wrap { + flex-wrap: wrap !important; + } + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + justify-content: flex-start !important; + } + .justify-content-md-end { + justify-content: flex-end !important; + } + .justify-content-md-center { + justify-content: center !important; + } + .justify-content-md-between { + justify-content: space-between !important; + } + .justify-content-md-around { + justify-content: space-around !important; + } + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + .align-items-md-start { + align-items: flex-start !important; + } + .align-items-md-end { + align-items: flex-end !important; + } + .align-items-md-center { + align-items: center !important; + } + .align-items-md-baseline { + align-items: baseline !important; + } + .align-items-md-stretch { + align-items: stretch !important; + } + .align-content-md-start { + align-content: flex-start !important; + } + .align-content-md-end { + align-content: flex-end !important; + } + .align-content-md-center { + align-content: center !important; + } + .align-content-md-between { + align-content: space-between !important; + } + .align-content-md-around { + align-content: space-around !important; + } + .align-content-md-stretch { + align-content: stretch !important; + } + .align-self-md-auto { + align-self: auto !important; + } + .align-self-md-start { + align-self: flex-start !important; + } + .align-self-md-end { + align-self: flex-end !important; + } + .align-self-md-center { + align-self: center !important; + } + .align-self-md-baseline { + align-self: baseline !important; + } + .align-self-md-stretch { + align-self: stretch !important; + } + .order-md-first { + order: -1 !important; + } + .order-md-0 { + order: 0 !important; + } + .order-md-1 { + order: 1 !important; + } + .order-md-2 { + order: 2 !important; + } + .order-md-3 { + order: 3 !important; + } + .order-md-4 { + order: 4 !important; + } + .order-md-5 { + order: 5 !important; + } + .order-md-last { + order: 6 !important; + } + .m-md-0 { + margin: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-md-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-md-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-md-0 { + margin-top: 0 !important; + } + .mt-md-1 { + margin-top: 0.25rem !important; + } + .mt-md-2 { + margin-top: 0.5rem !important; + } + .mt-md-3 { + margin-top: 1rem !important; + } + .mt-md-4 { + margin-top: 1.5rem !important; + } + .mt-md-5 { + margin-top: 3rem !important; + } + .mt-md-auto { + margin-top: auto !important; + } + .me-md-0 { + margin-right: 0 !important; + } + .me-md-1 { + margin-right: 0.25rem !important; + } + .me-md-2 { + margin-right: 0.5rem !important; + } + .me-md-3 { + margin-right: 1rem !important; + } + .me-md-4 { + margin-right: 1.5rem !important; + } + .me-md-5 { + margin-right: 3rem !important; + } + .me-md-auto { + margin-right: auto !important; + } + .mb-md-0 { + margin-bottom: 0 !important; + } + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + .mb-md-3 { + margin-bottom: 1rem !important; + } + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + .mb-md-5 { + margin-bottom: 3rem !important; + } + .mb-md-auto { + margin-bottom: auto !important; + } + .ms-md-0 { + margin-left: 0 !important; + } + .ms-md-1 { + margin-left: 0.25rem !important; + } + .ms-md-2 { + margin-left: 0.5rem !important; + } + .ms-md-3 { + margin-left: 1rem !important; + } + .ms-md-4 { + margin-left: 1.5rem !important; + } + .ms-md-5 { + margin-left: 3rem !important; + } + .ms-md-auto { + margin-left: auto !important; + } + .p-md-0 { + padding: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-md-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-md-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-md-0 { + padding-top: 0 !important; + } + .pt-md-1 { + padding-top: 0.25rem !important; + } + .pt-md-2 { + padding-top: 0.5rem !important; + } + .pt-md-3 { + padding-top: 1rem !important; + } + .pt-md-4 { + padding-top: 1.5rem !important; + } + .pt-md-5 { + padding-top: 3rem !important; + } + .pe-md-0 { + padding-right: 0 !important; + } + .pe-md-1 { + padding-right: 0.25rem !important; + } + .pe-md-2 { + padding-right: 0.5rem !important; + } + .pe-md-3 { + padding-right: 1rem !important; + } + .pe-md-4 { + padding-right: 1.5rem !important; + } + .pe-md-5 { + padding-right: 3rem !important; + } + .pb-md-0 { + padding-bottom: 0 !important; + } + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + .pb-md-3 { + padding-bottom: 1rem !important; + } + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + .pb-md-5 { + padding-bottom: 3rem !important; + } + .ps-md-0 { + padding-left: 0 !important; + } + .ps-md-1 { + padding-left: 0.25rem !important; + } + .ps-md-2 { + padding-left: 0.5rem !important; + } + .ps-md-3 { + padding-left: 1rem !important; + } + .ps-md-4 { + padding-left: 1.5rem !important; + } + .ps-md-5 { + padding-left: 3rem !important; + } + .gap-md-0 { + gap: 0 !important; + } + .gap-md-1 { + gap: 0.25rem !important; + } + .gap-md-2 { + gap: 0.5rem !important; + } + .gap-md-3 { + gap: 1rem !important; + } + .gap-md-4 { + gap: 1.5rem !important; + } + .gap-md-5 { + gap: 3rem !important; + } + .text-md-start { + text-align: left !important; + } + .text-md-end { + text-align: right !important; + } + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .float-lg-start { + float: left !important; + } + .float-lg-end { + float: right !important; + } + .float-lg-none { + float: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-grid { + display: grid !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: flex !important; + } + .d-lg-inline-flex { + display: inline-flex !important; + } + .d-lg-none { + display: none !important; + } + .flex-lg-fill { + flex: 1 1 auto !important; + } + .flex-lg-row { + flex-direction: row !important; + } + .flex-lg-column { + flex-direction: column !important; + } + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + .flex-lg-wrap { + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + justify-content: flex-start !important; + } + .justify-content-lg-end { + justify-content: flex-end !important; + } + .justify-content-lg-center { + justify-content: center !important; + } + .justify-content-lg-between { + justify-content: space-between !important; + } + .justify-content-lg-around { + justify-content: space-around !important; + } + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + .align-items-lg-start { + align-items: flex-start !important; + } + .align-items-lg-end { + align-items: flex-end !important; + } + .align-items-lg-center { + align-items: center !important; + } + .align-items-lg-baseline { + align-items: baseline !important; + } + .align-items-lg-stretch { + align-items: stretch !important; + } + .align-content-lg-start { + align-content: flex-start !important; + } + .align-content-lg-end { + align-content: flex-end !important; + } + .align-content-lg-center { + align-content: center !important; + } + .align-content-lg-between { + align-content: space-between !important; + } + .align-content-lg-around { + align-content: space-around !important; + } + .align-content-lg-stretch { + align-content: stretch !important; + } + .align-self-lg-auto { + align-self: auto !important; + } + .align-self-lg-start { + align-self: flex-start !important; + } + .align-self-lg-end { + align-self: flex-end !important; + } + .align-self-lg-center { + align-self: center !important; + } + .align-self-lg-baseline { + align-self: baseline !important; + } + .align-self-lg-stretch { + align-self: stretch !important; + } + .order-lg-first { + order: -1 !important; + } + .order-lg-0 { + order: 0 !important; + } + .order-lg-1 { + order: 1 !important; + } + .order-lg-2 { + order: 2 !important; + } + .order-lg-3 { + order: 3 !important; + } + .order-lg-4 { + order: 4 !important; + } + .order-lg-5 { + order: 5 !important; + } + .order-lg-last { + order: 6 !important; + } + .m-lg-0 { + margin: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-lg-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-lg-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-lg-0 { + margin-top: 0 !important; + } + .mt-lg-1 { + margin-top: 0.25rem !important; + } + .mt-lg-2 { + margin-top: 0.5rem !important; + } + .mt-lg-3 { + margin-top: 1rem !important; + } + .mt-lg-4 { + margin-top: 1.5rem !important; + } + .mt-lg-5 { + margin-top: 3rem !important; + } + .mt-lg-auto { + margin-top: auto !important; + } + .me-lg-0 { + margin-right: 0 !important; + } + .me-lg-1 { + margin-right: 0.25rem !important; + } + .me-lg-2 { + margin-right: 0.5rem !important; + } + .me-lg-3 { + margin-right: 1rem !important; + } + .me-lg-4 { + margin-right: 1.5rem !important; + } + .me-lg-5 { + margin-right: 3rem !important; + } + .me-lg-auto { + margin-right: auto !important; + } + .mb-lg-0 { + margin-bottom: 0 !important; + } + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + .mb-lg-3 { + margin-bottom: 1rem !important; + } + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + .mb-lg-5 { + margin-bottom: 3rem !important; + } + .mb-lg-auto { + margin-bottom: auto !important; + } + .ms-lg-0 { + margin-left: 0 !important; + } + .ms-lg-1 { + margin-left: 0.25rem !important; + } + .ms-lg-2 { + margin-left: 0.5rem !important; + } + .ms-lg-3 { + margin-left: 1rem !important; + } + .ms-lg-4 { + margin-left: 1.5rem !important; + } + .ms-lg-5 { + margin-left: 3rem !important; + } + .ms-lg-auto { + margin-left: auto !important; + } + .p-lg-0 { + padding: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-lg-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-lg-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-lg-0 { + padding-top: 0 !important; + } + .pt-lg-1 { + padding-top: 0.25rem !important; + } + .pt-lg-2 { + padding-top: 0.5rem !important; + } + .pt-lg-3 { + padding-top: 1rem !important; + } + .pt-lg-4 { + padding-top: 1.5rem !important; + } + .pt-lg-5 { + padding-top: 3rem !important; + } + .pe-lg-0 { + padding-right: 0 !important; + } + .pe-lg-1 { + padding-right: 0.25rem !important; + } + .pe-lg-2 { + padding-right: 0.5rem !important; + } + .pe-lg-3 { + padding-right: 1rem !important; + } + .pe-lg-4 { + padding-right: 1.5rem !important; + } + .pe-lg-5 { + padding-right: 3rem !important; + } + .pb-lg-0 { + padding-bottom: 0 !important; + } + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + .pb-lg-3 { + padding-bottom: 1rem !important; + } + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + .pb-lg-5 { + padding-bottom: 3rem !important; + } + .ps-lg-0 { + padding-left: 0 !important; + } + .ps-lg-1 { + padding-left: 0.25rem !important; + } + .ps-lg-2 { + padding-left: 0.5rem !important; + } + .ps-lg-3 { + padding-left: 1rem !important; + } + .ps-lg-4 { + padding-left: 1.5rem !important; + } + .ps-lg-5 { + padding-left: 3rem !important; + } + .gap-lg-0 { + gap: 0 !important; + } + .gap-lg-1 { + gap: 0.25rem !important; + } + .gap-lg-2 { + gap: 0.5rem !important; + } + .gap-lg-3 { + gap: 1rem !important; + } + .gap-lg-4 { + gap: 1.5rem !important; + } + .gap-lg-5 { + gap: 3rem !important; + } + .text-lg-start { + text-align: left !important; + } + .text-lg-end { + text-align: right !important; + } + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .float-xl-start { + float: left !important; + } + .float-xl-end { + float: right !important; + } + .float-xl-none { + float: none !important; + } + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-grid { + display: grid !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: flex !important; + } + .d-xl-inline-flex { + display: inline-flex !important; + } + .d-xl-none { + display: none !important; + } + .flex-xl-fill { + flex: 1 1 auto !important; + } + .flex-xl-row { + flex-direction: row !important; + } + .flex-xl-column { + flex-direction: column !important; + } + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xl-wrap { + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + justify-content: flex-start !important; + } + .justify-content-xl-end { + justify-content: flex-end !important; + } + .justify-content-xl-center { + justify-content: center !important; + } + .justify-content-xl-between { + justify-content: space-between !important; + } + .justify-content-xl-around { + justify-content: space-around !important; + } + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + .align-items-xl-start { + align-items: flex-start !important; + } + .align-items-xl-end { + align-items: flex-end !important; + } + .align-items-xl-center { + align-items: center !important; + } + .align-items-xl-baseline { + align-items: baseline !important; + } + .align-items-xl-stretch { + align-items: stretch !important; + } + .align-content-xl-start { + align-content: flex-start !important; + } + .align-content-xl-end { + align-content: flex-end !important; + } + .align-content-xl-center { + align-content: center !important; + } + .align-content-xl-between { + align-content: space-between !important; + } + .align-content-xl-around { + align-content: space-around !important; + } + .align-content-xl-stretch { + align-content: stretch !important; + } + .align-self-xl-auto { + align-self: auto !important; + } + .align-self-xl-start { + align-self: flex-start !important; + } + .align-self-xl-end { + align-self: flex-end !important; + } + .align-self-xl-center { + align-self: center !important; + } + .align-self-xl-baseline { + align-self: baseline !important; + } + .align-self-xl-stretch { + align-self: stretch !important; + } + .order-xl-first { + order: -1 !important; + } + .order-xl-0 { + order: 0 !important; + } + .order-xl-1 { + order: 1 !important; + } + .order-xl-2 { + order: 2 !important; + } + .order-xl-3 { + order: 3 !important; + } + .order-xl-4 { + order: 4 !important; + } + .order-xl-5 { + order: 5 !important; + } + .order-xl-last { + order: 6 !important; + } + .m-xl-0 { + margin: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-xl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-xl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xl-0 { + margin-top: 0 !important; + } + .mt-xl-1 { + margin-top: 0.25rem !important; + } + .mt-xl-2 { + margin-top: 0.5rem !important; + } + .mt-xl-3 { + margin-top: 1rem !important; + } + .mt-xl-4 { + margin-top: 1.5rem !important; + } + .mt-xl-5 { + margin-top: 3rem !important; + } + .mt-xl-auto { + margin-top: auto !important; + } + .me-xl-0 { + margin-right: 0 !important; + } + .me-xl-1 { + margin-right: 0.25rem !important; + } + .me-xl-2 { + margin-right: 0.5rem !important; + } + .me-xl-3 { + margin-right: 1rem !important; + } + .me-xl-4 { + margin-right: 1.5rem !important; + } + .me-xl-5 { + margin-right: 3rem !important; + } + .me-xl-auto { + margin-right: auto !important; + } + .mb-xl-0 { + margin-bottom: 0 !important; + } + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xl-3 { + margin-bottom: 1rem !important; + } + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xl-5 { + margin-bottom: 3rem !important; + } + .mb-xl-auto { + margin-bottom: auto !important; + } + .ms-xl-0 { + margin-left: 0 !important; + } + .ms-xl-1 { + margin-left: 0.25rem !important; + } + .ms-xl-2 { + margin-left: 0.5rem !important; + } + .ms-xl-3 { + margin-left: 1rem !important; + } + .ms-xl-4 { + margin-left: 1.5rem !important; + } + .ms-xl-5 { + margin-left: 3rem !important; + } + .ms-xl-auto { + margin-left: auto !important; + } + .p-xl-0 { + padding: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-xl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-xl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xl-0 { + padding-top: 0 !important; + } + .pt-xl-1 { + padding-top: 0.25rem !important; + } + .pt-xl-2 { + padding-top: 0.5rem !important; + } + .pt-xl-3 { + padding-top: 1rem !important; + } + .pt-xl-4 { + padding-top: 1.5rem !important; + } + .pt-xl-5 { + padding-top: 3rem !important; + } + .pe-xl-0 { + padding-right: 0 !important; + } + .pe-xl-1 { + padding-right: 0.25rem !important; + } + .pe-xl-2 { + padding-right: 0.5rem !important; + } + .pe-xl-3 { + padding-right: 1rem !important; + } + .pe-xl-4 { + padding-right: 1.5rem !important; + } + .pe-xl-5 { + padding-right: 3rem !important; + } + .pb-xl-0 { + padding-bottom: 0 !important; + } + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xl-3 { + padding-bottom: 1rem !important; + } + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xl-5 { + padding-bottom: 3rem !important; + } + .ps-xl-0 { + padding-left: 0 !important; + } + .ps-xl-1 { + padding-left: 0.25rem !important; + } + .ps-xl-2 { + padding-left: 0.5rem !important; + } + .ps-xl-3 { + padding-left: 1rem !important; + } + .ps-xl-4 { + padding-left: 1.5rem !important; + } + .ps-xl-5 { + padding-left: 3rem !important; + } + .gap-xl-0 { + gap: 0 !important; + } + .gap-xl-1 { + gap: 0.25rem !important; + } + .gap-xl-2 { + gap: 0.5rem !important; + } + .gap-xl-3 { + gap: 1rem !important; + } + .gap-xl-4 { + gap: 1.5rem !important; + } + .gap-xl-5 { + gap: 3rem !important; + } + .text-xl-start { + text-align: left !important; + } + .text-xl-end { + text-align: right !important; + } + .text-xl-center { + text-align: center !important; + } +} +@media (min-width: 1400px) { + .float-xxl-start { + float: left !important; + } + .float-xxl-end { + float: right !important; + } + .float-xxl-none { + float: none !important; + } + .d-xxl-inline { + display: inline !important; + } + .d-xxl-inline-block { + display: inline-block !important; + } + .d-xxl-block { + display: block !important; + } + .d-xxl-grid { + display: grid !important; + } + .d-xxl-table { + display: table !important; + } + .d-xxl-table-row { + display: table-row !important; + } + .d-xxl-table-cell { + display: table-cell !important; + } + .d-xxl-flex { + display: flex !important; + } + .d-xxl-inline-flex { + display: inline-flex !important; + } + .d-xxl-none { + display: none !important; + } + .flex-xxl-fill { + flex: 1 1 auto !important; + } + .flex-xxl-row { + flex-direction: row !important; + } + .flex-xxl-column { + flex-direction: column !important; + } + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xxl-start { + justify-content: flex-start !important; + } + .justify-content-xxl-end { + justify-content: flex-end !important; + } + .justify-content-xxl-center { + justify-content: center !important; + } + .justify-content-xxl-between { + justify-content: space-between !important; + } + .justify-content-xxl-around { + justify-content: space-around !important; + } + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + .align-items-xxl-start { + align-items: flex-start !important; + } + .align-items-xxl-end { + align-items: flex-end !important; + } + .align-items-xxl-center { + align-items: center !important; + } + .align-items-xxl-baseline { + align-items: baseline !important; + } + .align-items-xxl-stretch { + align-items: stretch !important; + } + .align-content-xxl-start { + align-content: flex-start !important; + } + .align-content-xxl-end { + align-content: flex-end !important; + } + .align-content-xxl-center { + align-content: center !important; + } + .align-content-xxl-between { + align-content: space-between !important; + } + .align-content-xxl-around { + align-content: space-around !important; + } + .align-content-xxl-stretch { + align-content: stretch !important; + } + .align-self-xxl-auto { + align-self: auto !important; + } + .align-self-xxl-start { + align-self: flex-start !important; + } + .align-self-xxl-end { + align-self: flex-end !important; + } + .align-self-xxl-center { + align-self: center !important; + } + .align-self-xxl-baseline { + align-self: baseline !important; + } + .align-self-xxl-stretch { + align-self: stretch !important; + } + .order-xxl-first { + order: -1 !important; + } + .order-xxl-0 { + order: 0 !important; + } + .order-xxl-1 { + order: 1 !important; + } + .order-xxl-2 { + order: 2 !important; + } + .order-xxl-3 { + order: 3 !important; + } + .order-xxl-4 { + order: 4 !important; + } + .order-xxl-5 { + order: 5 !important; + } + .order-xxl-last { + order: 6 !important; + } + .m-xxl-0 { + margin: 0 !important; + } + .m-xxl-1 { + margin: 0.25rem !important; + } + .m-xxl-2 { + margin: 0.5rem !important; + } + .m-xxl-3 { + margin: 1rem !important; + } + .m-xxl-4 { + margin: 1.5rem !important; + } + .m-xxl-5 { + margin: 3rem !important; + } + .m-xxl-auto { + margin: auto !important; + } + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-xxl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-xxl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xxl-0 { + margin-top: 0 !important; + } + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + .mt-xxl-3 { + margin-top: 1rem !important; + } + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + .mt-xxl-5 { + margin-top: 3rem !important; + } + .mt-xxl-auto { + margin-top: auto !important; + } + .me-xxl-0 { + margin-right: 0 !important; + } + .me-xxl-1 { + margin-right: 0.25rem !important; + } + .me-xxl-2 { + margin-right: 0.5rem !important; + } + .me-xxl-3 { + margin-right: 1rem !important; + } + .me-xxl-4 { + margin-right: 1.5rem !important; + } + .me-xxl-5 { + margin-right: 3rem !important; + } + .me-xxl-auto { + margin-right: auto !important; + } + .mb-xxl-0 { + margin-bottom: 0 !important; + } + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + .mb-xxl-auto { + margin-bottom: auto !important; + } + .ms-xxl-0 { + margin-left: 0 !important; + } + .ms-xxl-1 { + margin-left: 0.25rem !important; + } + .ms-xxl-2 { + margin-left: 0.5rem !important; + } + .ms-xxl-3 { + margin-left: 1rem !important; + } + .ms-xxl-4 { + margin-left: 1.5rem !important; + } + .ms-xxl-5 { + margin-left: 3rem !important; + } + .ms-xxl-auto { + margin-left: auto !important; + } + .p-xxl-0 { + padding: 0 !important; + } + .p-xxl-1 { + padding: 0.25rem !important; + } + .p-xxl-2 { + padding: 0.5rem !important; + } + .p-xxl-3 { + padding: 1rem !important; + } + .p-xxl-4 { + padding: 1.5rem !important; + } + .p-xxl-5 { + padding: 3rem !important; + } + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-xxl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-xxl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xxl-0 { + padding-top: 0 !important; + } + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + .pt-xxl-3 { + padding-top: 1rem !important; + } + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + .pt-xxl-5 { + padding-top: 3rem !important; + } + .pe-xxl-0 { + padding-right: 0 !important; + } + .pe-xxl-1 { + padding-right: 0.25rem !important; + } + .pe-xxl-2 { + padding-right: 0.5rem !important; + } + .pe-xxl-3 { + padding-right: 1rem !important; + } + .pe-xxl-4 { + padding-right: 1.5rem !important; + } + .pe-xxl-5 { + padding-right: 3rem !important; + } + .pb-xxl-0 { + padding-bottom: 0 !important; + } + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + .ps-xxl-0 { + padding-left: 0 !important; + } + .ps-xxl-1 { + padding-left: 0.25rem !important; + } + .ps-xxl-2 { + padding-left: 0.5rem !important; + } + .ps-xxl-3 { + padding-left: 1rem !important; + } + .ps-xxl-4 { + padding-left: 1.5rem !important; + } + .ps-xxl-5 { + padding-left: 3rem !important; + } + .gap-xxl-0 { + gap: 0 !important; + } + .gap-xxl-1 { + gap: 0.25rem !important; + } + .gap-xxl-2 { + gap: 0.5rem !important; + } + .gap-xxl-3 { + gap: 1rem !important; + } + .gap-xxl-4 { + gap: 1.5rem !important; + } + .gap-xxl-5 { + gap: 3rem !important; + } + .text-xxl-start { + text-align: left !important; + } + .text-xxl-end { + text-align: right !important; + } + .text-xxl-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .fs-1 { + font-size: 2.5rem !important; + } + .fs-2 { + font-size: 2rem !important; + } + .fs-3 { + font-size: 1.75rem !important; + } + .fs-4 { + font-size: 1.5rem !important; + } +} +@media print { + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-grid { + display: grid !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: flex !important; + } + .d-print-inline-flex { + display: inline-flex !important; + } + .d-print-none { + display: none !important; + } +} +.btn-klavesa { + color: #333; + background-color: #cfe2ff; + border-color: #73aaff; +} +.btn-klavesa:focus, .btn-klavesa.focus { + color: #333; + background-color: #9cc3ff; + border-color: #0060f2; +} +.btn-klavesa:hover { + color: #333; + background-color: #9cc3ff; + border-color: #3585ff; +} +.btn-klavesa:active, .btn-klavesa.active, .open > .btn-klavesa.dropdown-toggle { + color: #333; + background-color: #9cc3ff; + border-color: #3585ff; +} +.btn-klavesa:active:hover, .btn-klavesa:active:focus, .btn-klavesa:active.focus, .btn-klavesa.active:hover, .btn-klavesa.active:focus, .btn-klavesa.active.focus, .open > .btn-klavesa.dropdown-toggle:hover, .open > .btn-klavesa.dropdown-toggle:focus, .open > .btn-klavesa.dropdown-toggle.focus { + color: #333; + background-color: #78aeff; + border-color: #0060f2; +} +.btn-klavesa:active, .btn-klavesa.active, .open > .btn-klavesa.dropdown-toggle { + background-image: none; +} +.btn-klavesa.disabled, .btn-klavesa.disabled:hover, .btn-klavesa.disabled:focus, .btn-klavesa.disabled.focus, .btn-klavesa.disabled:active, .btn-klavesa.disabled.active, .btn-klavesa[disabled], .btn-klavesa[disabled]:hover, .btn-klavesa[disabled]:focus, .btn-klavesa[disabled].focus, .btn-klavesa[disabled]:active, .btn-klavesa[disabled].active, fieldset[disabled] .btn-klavesa, fieldset[disabled] .btn-klavesa:hover, fieldset[disabled] .btn-klavesa:focus, fieldset[disabled] .btn-klavesa.focus, fieldset[disabled] .btn-klavesa:active, fieldset[disabled] .btn-klavesa.active { + background-color: #cfe2ff; + border-color: #73aaff; +} + +.btn-klavesaDEL { + color: #333; + background-color: #f1aeb5; + border-color: #e56774; +} +.btn-klavesaDEL:focus, .btn-klavesaDEL.focus { + color: #333; + background-color: #e9838d; + border-color: #ae1e2d; +} +.btn-klavesaDEL:hover { + color: #333; + background-color: #e9838d; + border-color: #dc3345; +} +.btn-klavesaDEL:active, .btn-klavesaDEL.active, .open > .btn-klavesaDEL.dropdown-toggle { + color: #333; + background-color: #e9838d; + border-color: #dc3345; +} +.btn-klavesaDEL:active:hover, .btn-klavesaDEL:active:focus, .btn-klavesaDEL:active.focus, .btn-klavesaDEL.active:hover, .btn-klavesaDEL.active:focus, .btn-klavesaDEL.active.focus, .open > .btn-klavesaDEL.dropdown-toggle:hover, .open > .btn-klavesaDEL.dropdown-toggle:focus, .open > .btn-klavesaDEL.dropdown-toggle.focus { + color: #333; + background-color: #e46471; + border-color: #ae1e2d; +} +.btn-klavesaDEL:active, .btn-klavesaDEL.active, .open > .btn-klavesaDEL.dropdown-toggle { + background-image: none; +} +.btn-klavesaDEL.disabled, .btn-klavesaDEL.disabled:hover, .btn-klavesaDEL.disabled:focus, .btn-klavesaDEL.disabled.focus, .btn-klavesaDEL.disabled:active, .btn-klavesaDEL.disabled.active, .btn-klavesaDEL[disabled], .btn-klavesaDEL[disabled]:hover, .btn-klavesaDEL[disabled]:focus, .btn-klavesaDEL[disabled].focus, .btn-klavesaDEL[disabled]:active, .btn-klavesaDEL[disabled].active, fieldset[disabled] .btn-klavesaDEL, fieldset[disabled] .btn-klavesaDEL:hover, fieldset[disabled] .btn-klavesaDEL:focus, fieldset[disabled] .btn-klavesaDEL.focus, fieldset[disabled] .btn-klavesaDEL:active, fieldset[disabled] .btn-klavesaDEL.active { + background-color: #f1aeb5; + border-color: #e56774; +} + +.btn-klavesaZPET { + color: #333; + background-color: #ced4da; + border-color: #9eaab6; +} +.btn-klavesaZPET:focus, .btn-klavesaZPET.focus { + color: #333; + background-color: #b1bbc4; + border-color: #5b6a79; +} +.btn-klavesaZPET:hover { + color: #333; + background-color: #b1bbc4; + border-color: #7b8b9b; +} +.btn-klavesaZPET:active, .btn-klavesaZPET.active, .open > .btn-klavesaZPET.dropdown-toggle { + color: #333; + background-color: #b1bbc4; + border-color: #7b8b9b; +} +.btn-klavesaZPET:active:hover, .btn-klavesaZPET:active:focus, .btn-klavesaZPET:active.focus, .btn-klavesaZPET.active:hover, .btn-klavesaZPET.active:focus, .btn-klavesaZPET.active.focus, .open > .btn-klavesaZPET.dropdown-toggle:hover, .open > .btn-klavesaZPET.dropdown-toggle:focus, .open > .btn-klavesaZPET.dropdown-toggle.focus { + color: #333; + background-color: #9da9b5; + border-color: #5b6a79; +} +.btn-klavesaZPET:active, .btn-klavesaZPET.active, .open > .btn-klavesaZPET.dropdown-toggle { + background-image: none; +} +.btn-klavesaZPET.disabled, .btn-klavesaZPET.disabled:hover, .btn-klavesaZPET.disabled:focus, .btn-klavesaZPET.disabled.focus, .btn-klavesaZPET.disabled:active, .btn-klavesaZPET.disabled.active, .btn-klavesaZPET[disabled], .btn-klavesaZPET[disabled]:hover, .btn-klavesaZPET[disabled]:focus, .btn-klavesaZPET[disabled].focus, .btn-klavesaZPET[disabled]:active, .btn-klavesaZPET[disabled].active, fieldset[disabled] .btn-klavesaZPET, fieldset[disabled] .btn-klavesaZPET:hover, fieldset[disabled] .btn-klavesaZPET:focus, fieldset[disabled] .btn-klavesaZPET.focus, fieldset[disabled] .btn-klavesaZPET:active, fieldset[disabled] .btn-klavesaZPET.active { + background-color: #ced4da; + border-color: #9eaab6; +} + +.btn-klient { + color: #333; + background-color: #a6dbb8; + border-color: #6fc58c; +} +.btn-klient:focus, .btn-klient.focus { + color: #333; + background-color: #82cc9b; + border-color: #34814e; +} +.btn-klient:hover { + color: #333; + background-color: #82cc9b; + border-color: #47b06b; +} +.btn-klient:active, .btn-klient.active, .open > .btn-klient.dropdown-toggle { + color: #333; + background-color: #82cc9b; + border-color: #47b06b; +} +.btn-klient:active:hover, .btn-klient:active:focus, .btn-klient:active.focus, .btn-klient.active:hover, .btn-klient.active:focus, .btn-klient.active.focus, .open > .btn-klient.dropdown-toggle:hover, .open > .btn-klient.dropdown-toggle:focus, .open > .btn-klient.dropdown-toggle.focus { + color: #333; + background-color: #68c287; + border-color: #34814e; +} +.btn-klient:active, .btn-klient.active, .open > .btn-klient.dropdown-toggle { + background-image: none; +} +.btn-klient.disabled, .btn-klient.disabled:hover, .btn-klient.disabled:focus, .btn-klient.disabled.focus, .btn-klient.disabled:active, .btn-klient.disabled.active, .btn-klient[disabled], .btn-klient[disabled]:hover, .btn-klient[disabled]:focus, .btn-klient[disabled].focus, .btn-klient[disabled]:active, .btn-klient[disabled].active, fieldset[disabled] .btn-klient, fieldset[disabled] .btn-klient:hover, fieldset[disabled] .btn-klient:focus, fieldset[disabled] .btn-klient.focus, fieldset[disabled] .btn-klient:active, fieldset[disabled] .btn-klient.active { + background-color: #a6dbb8; + border-color: #6fc58c; +} + +.btn-warning { + color: #333; + background-color: #f9cf9b; + border-color: #f4aa4f; +} +.btn-warning:focus, .btn-warning.focus { + color: #333; + background-color: #f6b86b; + border-color: #b96b0b; +} +.btn-warning:hover { + color: #333; + background-color: #f6b86b; + border-color: #f18f15; +} +.btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { + color: #333; + background-color: #f6b86b; + border-color: #f18f15; +} +.btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, .open > .btn-warning.dropdown-toggle:hover, .open > .btn-warning.dropdown-toggle:focus, .open > .btn-warning.dropdown-toggle.focus { + color: #333; + background-color: #f4a849; + border-color: #b96b0b; +} +.btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { + background-image: none; +} +.btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active { + background-color: #f9cf9b; + border-color: #f4aa4f; +} + +.btn-zavrit { + color: #333; + background-color: #fa8f8f; + border-color: #f74444; +} +.btn-zavrit:focus, .btn-zavrit.focus { + color: #333; + background-color: #f85e5e; + border-color: #b30808; +} +.btn-zavrit:hover { + color: #333; + background-color: #f85e5e; + border-color: #f20b0b; +} +.btn-zavrit:active, .btn-zavrit.active, .open > .btn-zavrit.dropdown-toggle { + color: #333; + background-color: #f85e5e; + border-color: #f20b0b; +} +.btn-zavrit:active:hover, .btn-zavrit:active:focus, .btn-zavrit:active.focus, .btn-zavrit.active:hover, .btn-zavrit.active:focus, .btn-zavrit.active.focus, .open > .btn-zavrit.dropdown-toggle:hover, .open > .btn-zavrit.dropdown-toggle:focus, .open > .btn-zavrit.dropdown-toggle.focus { + color: #333; + background-color: #f63c3c; + border-color: #b30808; +} +.btn-zavrit:active, .btn-zavrit.active, .open > .btn-zavrit.dropdown-toggle { + background-image: none; +} +.btn-zavrit.disabled, .btn-zavrit.disabled:hover, .btn-zavrit.disabled:focus, .btn-zavrit.disabled.focus, .btn-zavrit.disabled:active, .btn-zavrit.disabled.active, .btn-zavrit[disabled], .btn-zavrit[disabled]:hover, .btn-zavrit[disabled]:focus, .btn-zavrit[disabled].focus, .btn-zavrit[disabled]:active, .btn-zavrit[disabled].active, fieldset[disabled] .btn-zavrit, fieldset[disabled] .btn-zavrit:hover, fieldset[disabled] .btn-zavrit:focus, fieldset[disabled] .btn-zavrit.focus, fieldset[disabled] .btn-zavrit:active, fieldset[disabled] .btn-zavrit.active { + background-color: #fa8f8f; + border-color: #f74444; +} + +.btn-dochazka-start { + color: #333; + background-color: #f8e1c5; + border-color: #eeb876; +} +.btn-dochazka-start:focus, .btn-dochazka-start.focus { + color: #333; + background-color: #f3c997; + border-color: #cc7b19; +} +.btn-dochazka-start:hover { + color: #333; + background-color: #f3c997; + border-color: #e89c3f; +} +.btn-dochazka-start:active, .btn-dochazka-start.active, .open > .btn-dochazka-start.dropdown-toggle { + color: #333; + background-color: #f3c997; + border-color: #e89c3f; +} +.btn-dochazka-start:active:hover, .btn-dochazka-start:active:focus, .btn-dochazka-start:active.focus, .btn-dochazka-start.active:hover, .btn-dochazka-start.active:focus, .btn-dochazka-start.active.focus, .open > .btn-dochazka-start.dropdown-toggle:hover, .open > .btn-dochazka-start.dropdown-toggle:focus, .open > .btn-dochazka-start.dropdown-toggle.focus { + color: #333; + background-color: #efb978; + border-color: #cc7b19; +} +.btn-dochazka-start:active, .btn-dochazka-start.active, .open > .btn-dochazka-start.dropdown-toggle { + background-image: none; +} +.btn-dochazka-start.disabled, .btn-dochazka-start.disabled:hover, .btn-dochazka-start.disabled:focus, .btn-dochazka-start.disabled.focus, .btn-dochazka-start.disabled:active, .btn-dochazka-start.disabled.active, .btn-dochazka-start[disabled], .btn-dochazka-start[disabled]:hover, .btn-dochazka-start[disabled]:focus, .btn-dochazka-start[disabled].focus, .btn-dochazka-start[disabled]:active, .btn-dochazka-start[disabled].active, fieldset[disabled] .btn-dochazka-start, fieldset[disabled] .btn-dochazka-start:hover, fieldset[disabled] .btn-dochazka-start:focus, fieldset[disabled] .btn-dochazka-start.focus, fieldset[disabled] .btn-dochazka-start:active, fieldset[disabled] .btn-dochazka-start.active { + background-color: #f8e1c5; + border-color: #eeb876; +} + +.btn-dochazka-konec { + color: #333; + background-color: #fcbaba; + border-color: #f86666; +} +.btn-dochazka-konec:focus, .btn-dochazka-konec.focus { + color: #333; + background-color: #fa8989; + border-color: #d60909; +} +.btn-dochazka-konec:hover { + color: #333; + background-color: #fa8989; + border-color: #f62b2b; +} +.btn-dochazka-konec:active, .btn-dochazka-konec.active, .open > .btn-dochazka-konec.dropdown-toggle { + color: #333; + background-color: #fa8989; + border-color: #f62b2b; +} +.btn-dochazka-konec:active:hover, .btn-dochazka-konec:active:focus, .btn-dochazka-konec:active.focus, .btn-dochazka-konec.active:hover, .btn-dochazka-konec.active:focus, .btn-dochazka-konec.active.focus, .open > .btn-dochazka-konec.dropdown-toggle:hover, .open > .btn-dochazka-konec.dropdown-toggle:focus, .open > .btn-dochazka-konec.dropdown-toggle.focus { + color: #333; + background-color: #f86767; + border-color: #d60909; +} +.btn-dochazka-konec:active, .btn-dochazka-konec.active, .open > .btn-dochazka-konec.dropdown-toggle { + background-image: none; +} +.btn-dochazka-konec.disabled, .btn-dochazka-konec.disabled:hover, .btn-dochazka-konec.disabled:focus, .btn-dochazka-konec.disabled.focus, .btn-dochazka-konec.disabled:active, .btn-dochazka-konec.disabled.active, .btn-dochazka-konec[disabled], .btn-dochazka-konec[disabled]:hover, .btn-dochazka-konec[disabled]:focus, .btn-dochazka-konec[disabled].focus, .btn-dochazka-konec[disabled]:active, .btn-dochazka-konec[disabled].active, fieldset[disabled] .btn-dochazka-konec, fieldset[disabled] .btn-dochazka-konec:hover, fieldset[disabled] .btn-dochazka-konec:focus, fieldset[disabled] .btn-dochazka-konec.focus, fieldset[disabled] .btn-dochazka-konec:active, fieldset[disabled] .btn-dochazka-konec.active { + background-color: #fcbaba; + border-color: #f86666; +} + +.box-shadow--2dp { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); +} + +.box-shadow--3dp { + box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 1px 8px 0 rgba(0, 0, 0, 0.12); +} + +.box-shadow--4dp { + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2); +} + +.box-shadow--6dp { + box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.2); +} + +.box-shadow--8dp { + box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); +} + +.box-shadow--8dp-tlacitko-zp5 { + box-shadow: 0 0 5px 5px rgba(0, 0, 100, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); +} + +.box-shadow--16dp { + box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2); +} + +.badge-dulezitost1 { + --bs-badge-color: #000000; + background-color: #dbdbdb; +} + +.badge-dulezitost2 { + --bs-badge-color: #000; + background-color: #d1f6d1; +} + +.badge-dulezitost3 { + --bs-badge-color: #000; + background-color: #d1ecff; +} + +.badge-dulezitost4 { + --bs-badge-color: #000; + background-color: #ffecd1; +} + +.badge-dulezitost5 { + --bs-badge-color: #000; + background-color: #ffd1d1; +} + +.accordion-button-2 { + background-color: #fad2d2; +} +.accordion-button-2:not(.collapsed) { + color: var(--bs-accordion-active-color); + background-color: #fad2d2; + box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color); + color: var(--bs-danger); +} +.accordion-button-2:not(.collapsed)::after { + background-image: var(--bs-accordion-btn-active-icon); + transform: var(--bs-accordion-btn-icon-transform); +} +.accordion-button-2:focus { + z-index: 3; + border-color: #f98989; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(253, 13, 13, 0.25); +} + +/*# sourceMappingURL=bootstrap.min.css.map */ diff --git a/www/css/bootstrap.min.css.map b/www/css/bootstrap.min.css.map new file mode 100644 index 0000000..59b2a21 --- /dev/null +++ b/www/css/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../scss/node_modules/bootstrap-scss/mixins/_banner.scss","../scss/node_modules/bootstrap-scss/_root.scss","../scss/node_modules/bootstrap-scss/vendor/_rfs.scss","../scss/node_modules/bootstrap-scss/_reboot.scss","../scss/node_modules/bootstrap-scss/_variables.scss","../scss/node_modules/bootstrap-scss/mixins/_border-radius.scss","../scss/node_modules/bootstrap-scss/_type.scss","../scss/node_modules/bootstrap-scss/mixins/_lists.scss","../scss/node_modules/bootstrap-scss/_images.scss","../scss/node_modules/bootstrap-scss/mixins/_image.scss","../scss/node_modules/bootstrap-scss/_containers.scss","../scss/node_modules/bootstrap-scss/mixins/_container.scss","../scss/node_modules/bootstrap-scss/mixins/_breakpoints.scss","../scss/node_modules/bootstrap-scss/_grid.scss","../scss/node_modules/bootstrap-scss/mixins/_grid.scss","../scss/node_modules/bootstrap-scss/_tables.scss","../scss/node_modules/bootstrap-scss/mixins/_table-variants.scss","../scss/node_modules/bootstrap-scss/forms/_labels.scss","../scss/node_modules/bootstrap-scss/forms/_form-text.scss","../scss/node_modules/bootstrap-scss/forms/_form-control.scss","../scss/node_modules/bootstrap-scss/mixins/_transition.scss","../scss/node_modules/bootstrap-scss/mixins/_gradients.scss","../scss/node_modules/bootstrap-scss/forms/_form-select.scss","../scss/node_modules/bootstrap-scss/forms/_form-check.scss","../scss/node_modules/bootstrap-scss/forms/_form-range.scss","../scss/node_modules/bootstrap-scss/forms/_floating-labels.scss","../scss/node_modules/bootstrap-scss/forms/_input-group.scss","../scss/node_modules/bootstrap-scss/mixins/_forms.scss","../scss/node_modules/bootstrap-scss/_buttons.scss","../scss/node_modules/bootstrap-scss/mixins/_buttons.scss","../scss/node_modules/bootstrap-scss/_transitions.scss","../scss/node_modules/bootstrap-scss/_dropdown.scss","../scss/node_modules/bootstrap-scss/mixins/_caret.scss","../scss/node_modules/bootstrap-scss/_button-group.scss","../scss/node_modules/bootstrap-scss/_nav.scss","../scss/node_modules/bootstrap-scss/_navbar.scss","../scss/node_modules/bootstrap-scss/_card.scss","../scss/node_modules/bootstrap-scss/_accordion.scss","../scss/node_modules/bootstrap-scss/_breadcrumb.scss","../scss/node_modules/bootstrap-scss/_pagination.scss","../scss/node_modules/bootstrap-scss/mixins/_pagination.scss","../scss/node_modules/bootstrap-scss/_badge.scss","../scss/node_modules/bootstrap-scss/_alert.scss","../scss/node_modules/bootstrap-scss/mixins/_alert.scss","../scss/node_modules/bootstrap-scss/_progress.scss","../scss/node_modules/bootstrap-scss/_list-group.scss","../scss/node_modules/bootstrap-scss/mixins/_list-group.scss","../scss/node_modules/bootstrap-scss/_close.scss","../scss/node_modules/bootstrap-scss/_toasts.scss","../scss/node_modules/bootstrap-scss/_modal.scss","../scss/node_modules/bootstrap-scss/mixins/_backdrop.scss","../scss/node_modules/bootstrap-scss/_tooltip.scss","../scss/node_modules/bootstrap-scss/mixins/_reset-text.scss","../scss/node_modules/bootstrap-scss/_popover.scss","../scss/node_modules/bootstrap-scss/_carousel.scss","../scss/node_modules/bootstrap-scss/mixins/_clearfix.scss","../scss/node_modules/bootstrap-scss/_spinners.scss","../scss/node_modules/bootstrap-scss/_offcanvas.scss","../scss/node_modules/bootstrap-scss/_placeholders.scss","../scss/node_modules/bootstrap-scss/helpers/_color-bg.scss","../scss/node_modules/bootstrap-scss/helpers/_colored-links.scss","../scss/node_modules/bootstrap-scss/helpers/_ratio.scss","../scss/node_modules/bootstrap-scss/helpers/_position.scss","../scss/node_modules/bootstrap-scss/helpers/_stacks.scss","../scss/node_modules/bootstrap-scss/helpers/_visually-hidden.scss","../scss/node_modules/bootstrap-scss/mixins/_visually-hidden.scss","../scss/node_modules/bootstrap-scss/helpers/_stretched-link.scss","../scss/node_modules/bootstrap-scss/helpers/_text-truncation.scss","../scss/node_modules/bootstrap-scss/mixins/_text-truncate.scss","../scss/node_modules/bootstrap-scss/helpers/_vr.scss","../scss/node_modules/bootstrap-scss/mixins/_utilities.scss","../scss/node_modules/bootstrap-scss/utilities/_api.scss","../scss/custom.scss"],"names":[],"mappings":"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IAxDV;;EAwDU;IAxDV;;EAwDU;IAxDV;;EAwDU;IAxDV;;EAmEM;AAAA;IAEE;;EAGF;AAAA;IAEE;;EAPF;AAAA;IAEE;;EAGF;AAAA;IAEE;;EAPF;AAAA;IAEE;;EAGF;AAAA;IAEE;;EAPF;AAAA;IAEE;;EAGF;AAAA;IAEE;;EAPF;AAAA;IAEE;;EAGF;AAAA;IAEE;;EAPF;AAAA;IAEE;;EAGF;AAAA;IAEE;;;ACrHV;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA,eXoWO;EWnWP;EACA,gBXqoB4B;EWpoB5B;;AAOA;EACE;EACA;EACA,qBXic0B;EWhc1B;;AAGF;EACE;;AAGF;EACE;;;AAIJ;EACE;;;AAOF;EACE;;;AAUA;EACE;;;AAeF;EACE;;AAGA;EACE;;;AAOJ;EACE;;AAGF;EACE;;;AAUF;EACE;EACA;;;AAMF;EACE;EACA;;;AAQJ;EACE;EACA;;;AAQA;EACE;EACA;;;ACrIF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AAlBF;EAOE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;;;AD0IA;EACE;EACA;;;AHpFF;EGkFA;IACE;IACA;;;AHpFF;EGkFA;IACE;IACA;;;AHpFF;EGkFA;IACE;IACA;;;AHpFF;EGkFA;IACE;IACA;;;AHpFF;EGkFA;IACE;IACA;;;AE5JN;EACE,eb8xBsC;;;AarxBxC;EACE;EACA;EACA;EfoRI,WALI;Ee3QR,ab+hB4B;;;Aa3hB9B;EACE;EACA;Ef0QI,WALI;;;AejQV;EACE;EACA;EfoQI,WALI;;;AgB5RV;EACE,YdsxBsC;EFtflC,WALI;EgBvRR,OdKS;;;AeVX;EACE;EACA;EACA;EjB8RI,WALI;EiBtRR,afmiB4B;EeliB5B,afyiB4B;EexiB5B,OfKS;EeJT,kBfLS;EeMT;EACA;EACA;EdGE;EeHE,YDMJ;;ACFI;EDhBN;ICiBQ;;;ADGN;EACE;;AAEA;EACE;;AAKJ;EACE,OfjBO;EekBP,kBf3BO;Ee4BP,cfqyBoC;EepyBpC;EAKE,Yf6qB0B;;AetqB9B;EAEE;;AAIF;EACE,Of1CO;Ee4CP;;AAQF;EAEE,kBf1DO;Ee6DP;;AAIF;EACE;EACA;EACA,mBfgoB0B;Ee/nB1B,Of9DO;EiBbT,kBjBMS;EeuEP;EACA;EACA;EACA;EACA,yBf0Y0B;EezY1B;ECtEE,YDuEF;;ACnEE;EDuDJ;ICtDM;;;ADqEN;EACE,kBfs4B8B;;;Ae73BlC;EACE;EACA;EACA;EACA;EACA,af2c4B;Ee1c5B,OfzFS;Ee0FT;EACA;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;;;AAWJ;EACE,YfstBsC;EertBtC;EjBkKI,WALI;EG7QN;;AcoHF;EACE;EACA;EACA,mBfglB0B;;;Ae5kB9B;EACE,Yf0sBsC;EezsBtC;EjBqJI,WALI;EG7QN;;AciIF;EACE;EACA;EACA,mBfukB0B;;;Ae/jB5B;EACE,YfurBoC;;AeprBtC;EACE,YforBoC;;AejrBtC;EACE,YfirBoC;;;Ae5qBxC;EACE,Of+qBsC;Ee9qBtC,QfwqBsC;EevqBtC,Sf6hB4B;;Ae3hB5B;EACE;;AAGF;EACE;EdpKA;;AcwKF;EdxKE;;Ac4KF;EAAoB,QfypBkB;;AexpBtC;EAAoB,QfypBkB;;;AkBp1BxC;EACE;EACA;EACA;EACA;EpB4RI,WALI;EoBpRR,alBiiB4B;EkBhiB5B,alBuiB4B;EkBtiB5B,OlBGS;EkBFT,kBlBPS;EkBQT;EACA;EACA,qBlBw5BkC;EkBv5BlC,iBlBw5BkC;EkBv5BlC;EjBDE;EeHE,YEOJ;EACA;;AFJI;EEfN;IFgBQ;;;AEKN;EACE,clB8yBoC;EkB7yBpC;EAKE,YlBy5B4B;;AkBr5BhC;EAEE,elBuqB0B;EkBtqB1B;;AAGF;EAEE,kBlBnCO;;AkBwCT;EACE;EACA;;;AAIJ;EACE,alBgqB4B;EkB/pB5B,gBlB+pB4B;EkB9pB5B,clB+pB4B;EFrbxB,WALI;EG7QN;;;AiB6CJ;EACE,alB4pB4B;EkB3pB5B,gBlB2pB4B;EkB1pB5B,clB2pB4B;EFzbxB,WALI;EG7QN;;;AkBfJ;EACE;EACA,YnB41BwC;EmB31BxC,cnB41BwC;EmB31BxC,enB41BwC;;AmB11BxC;EACE;EACA;;;AAIJ;EACE,enBk1BwC;EmBj1BxC;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE,OnBo0BwC;EmBn0BxC,QnBm0BwC;EmBl0BxC;EACA;EACA,kBnBzBS;EmB0BT;EACA;EACA;EACA,QnBu0BwC;EmBt0BxC;EACA;;AAGA;ElBvBE;;AkB2BF;EAEE,enB8zBsC;;AmB3zBxC;EACE,QnBqzBsC;;AmBlzBxC;EACE,cnBixBoC;EmBhxBpC;EACA,YnB6pB4B;;AmB1pB9B;EACE,kBnBxBM;EmByBN,cnBzBM;;AmB2BN;EAII;;AAIJ;EAII;;AAKN;EACE,kBnB7CM;EmB8CN,cnB9CM;EmBmDJ;;AAIJ;EACE;EACA;EACA,SnB6xBuC;;AmBtxBvC;EACE;EACA,SnBoxBqC;;;AmBtwB3C;EACE,cnB+wBgC;;AmB7wBhC;EACE,OnB2wB8B;EmB1wB9B;EACA;EACA;ElB3GA;EeHE,YGgHF;;AH5GE;EGsGJ;IHrGM;;;AG6GJ;EACE;;AAGF;EACE,qBnB0wB4B;EmBrwB1B;;AAKN;EACE,enBqvB8B;EmBpvB9B;;AAEA;EACE;EACA;;;AAKN;EACE;EACA,cnBmuBgC;;;AmBhuBlC;EACE;EACA;EACA;;AAIE;EACE;EACA;EACA,SnBolBwB;;;AoBzvB9B;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIA;EAA0B,YpBq8Ba;;AoBp8BvC;EAA0B,YpBo8Ba;;AoBj8BzC;EACE;;AAGF;EACE,OpBs7BuC;EoBr7BvC,QpBq7BuC;EoBp7BvC;EHzBF,kBjBkCQ;EoBPN,QpBq7BuC;ECj8BvC;EeHE,YIkBF;EACA;;AJfE;EIMJ;IJLM;;;AIgBJ;EHjCF,kBjBq9ByC;;AoB/6BzC;EACE,OpB+5B8B;EoB95B9B,QpB+5B8B;EoB95B9B;EACA,QpB85B8B;EoB75B9B,kBpBpCO;EoBqCP;EnB7BA;;AmBkCF;EACE,OpB25BuC;EoB15BvC,QpB05BuC;EiB78BzC,kBjBkCQ;EoBmBN,QpB25BuC;ECj8BvC;EeHE,YI4CF;EACA;;AJzCE;EIiCJ;IJhCM;;;AI0CJ;EH3DF,kBjBq9ByC;;AoBr5BzC;EACE,OpBq4B8B;EoBp4B9B,QpBq4B8B;EoBp4B9B;EACA,QpBo4B8B;EoBn4B9B,kBpB9DO;EoB+DP;EnBvDA;;AmB4DF;EACE;;AAEA;EACE,kBpBtEK;;AoByEP;EACE,kBpB1EK;;;AqBbX;EACE;;AAEA;AAAA;AAAA;EAGE,QrB+9B8B;EqB99B9B,arB+9B8B;;AqB59BhC;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;ELPE,YKQF;;ALJE;EKVJ;ILWM;;;AKMN;AAAA;EAEE;;AAEA;AAAA;EACE;;AAGF;AAAA;AAAA;EAEE,arBo8B4B;EqBn8B5B,gBrBo8B4B;;AqBj8B9B;AAAA;EACE,arB+7B4B;EqB97B5B,gBrB+7B4B;;AqB37BhC;EACE,arBy7B8B;EqBx7B9B,gBrBy7B8B;;AqBl7B9B;AAAA;AAAA;AAAA;EACE,SrBk7B4B;EqBj7B5B,WrBk7B4B;;AqB76B9B;EACE,SrB26B4B;EqB16B5B,WrB26B4B;;AqBt6B9B;EACE;;;ACnEN;EACE;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;EAGE;EACA;EACA;EACA;;AAIF;AAAA;AAAA;EAGE;;AAMF;EACE;EACA;;AAEA;EACE;;;AAWN;EACE;EACA;EACA;ExBoPI,WALI;EwB7OR,atB0f4B;EsBzf5B,atBggB4B;EsB/f5B,OtBpCS;EsBqCT;EACA;EACA,kBtB9CS;EsB+CT;ErBtCE;;;AqBgDJ;AAAA;AAAA;AAAA;EAIE;ExB8NI,WALI;EG7QN;;;AqByDJ;AAAA;AAAA;AAAA;EAIE;ExBqNI,WALI;EG7QN;;;AqBkEJ;AAAA;EAEE;;;AAaE;AAAA;AAAA;AAAA;ErBjEA;EACA;;AqByEA;AAAA;AAAA;AAAA;ErB1EA;EACA;;AqBsFF;EACE;ErB1EA;EACA;;AqB6EF;AAAA;ErB9EE;EACA;;;AsBzBF;EACE;EACA;EACA,YvB+vBoC;EFtflC,WALI;EyBjQN,OvBi+BqB;;;AuB99BvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EzB4PE,WALI;EyBpPN,OAvBc;EAwBd,kBAvBiB;EtBHjB;;;AsB+BA;AAAA;AAAA;AAAA;EAEE;;;AA9CF;EAoDE,cvBs8BmB;EuBn8BjB,evBsxBgC;EuBrxBhC;EACA;EACA;EACA;;AAGF;EACE,cvB27BiB;EuB17BjB,YA/Ca;;;AAjBjB;EAyEI,evBowBgC;EuBnwBhC;;;AA1EJ;EAiFE,cvBy6BmB;;AuBt6BjB;EAEE,evBm1B8B;EuBl1B9B;EACA;EACA;;AAIJ;EACE,cvB45BiB;EuB35BjB,YA9Ea;;;AAjBjB;EAuGI;;;AAvGJ;EA8GE,cvB44BmB;;AuB14BnB;EACE,kBvBy4BiB;;AuBt4BnB;EACE,YApGa;;AAuGf;EACE,OvBi4BiB;;;AuB53BrB;EACE;;;AA/HF;AAAA;AAAA;AAAA;AAAA;EAyIM;;;AAtHR;EACE;EACA;EACA,YvB+vBoC;EFtflC,WALI;EyBjQN,OvBi+BqB;;;AuB99BvB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EzB4PE,WALI;EyBpPN,OAvBc;EAwBd,kBAvBiB;EtBHjB;;;AsB+BA;AAAA;AAAA;AAAA;EAEE;;;AA9CF;EAoDE,cvBs8BmB;EuBn8BjB,evBsxBgC;EuBrxBhC;EACA;EACA;EACA;;AAGF;EACE,cvB27BiB;EuB17BjB,YA/Ca;;;AAjBjB;EAyEI,evBowBgC;EuBnwBhC;;;AA1EJ;EAiFE,cvBy6BmB;;AuBt6BjB;EAEE,evBm1B8B;EuBl1B9B;EACA;EACA;;AAIJ;EACE,cvB45BiB;EuB35BjB,YA9Ea;;;AAjBjB;EAuGI;;;AAvGJ;EA8GE,cvB44BmB;;AuB14BnB;EACE,kBvBy4BiB;;AuBt4BnB;EACE,YApGa;;AAuGf;EACE,OvBi4BiB;;;AuB53BrB;EACE;;;AA/HF;AAAA;AAAA;AAAA;AAAA;EA2IM;;;AC7IV;EAEE;EACA;EACA;E1B6RI,oBALI;E0BtRR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;E1B4QI,WALI;E0BrQR;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EvBjBE;EgBfF,kBOkCqB;ERtBjB,YQwBJ;;ARpBI;EQhBN;IRiBQ;;;AQqBN;EACE;EAEA;EACA;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;EPrDF,kBOsDuB;EACrB;EACA;EAKE;;AAIJ;EACE;EACA;EAKE;;AAIJ;EAKE;EACA;EAGA;;AAGA;EAKI;;AAKN;EAGE;EACA;EACA;EAEA;EACA;;;AAYF;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADyFA;ECtGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADmHA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AD0FA;ECvGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ADsGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,iBxB2OwC;;AwBjOxC;EACE;;AAGF;EACE;;;AAWJ;ECxIE;EACA;E3BoOI,oBALI;E2B7NR;;;ADyIF;EC5IE;EACA;E3BoOI,oBALI;E2B7NR;;;ACnEF;EVgBM,YUfJ;;AVmBI;EUpBN;IVqBQ;;;AUlBN;EACE;;;AAMF;EACE;;;AAIJ;EACE;EACA;EVDI,YUEJ;;AVEI;EULN;IVMQ;;;AUDN;EACE;EACA;EVNE,YUOF;;AVHE;EUAJ;IVCM;;;;AWpBR;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;;AAGF;EACE;;ACmBE;EACE;EACA,a5BmewB;E4BlexB,gB5BiewB;E4BhexB;EAhCJ;EACA;EACA;EACA;;AAqDE;EACE;;;ADzCN;EAEE;EACA;EACA;EACA;EACA;E7B6QI,yBALI;E6BtQR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;E7BgPI,WALI;E6BzOR;EACA;EACA;EACA;EACA;EACA;E1BzCE;;A0B6CF;EACE;EACA;EACA;;;AAwBA;EACE;;AAEA;EACE;EACA;;;AAIJ;EACE;;AAEA;EACE;EACA;;;AnB1CJ;EmB4BA;IACE;;EAEA;IACE;IACA;;EAIJ;IACE;;EAEA;IACE;IACA;;;AnB1CJ;EmB4BA;IACE;;EAEA;IACE;IACA;;EAIJ;IACE;;EAEA;IACE;IACA;;;AnB1CJ;EmB4BA;IACE;;EAEA;IACE;IACA;;EAIJ;IACE;;EAEA;IACE;IACA;;;AnB1CJ;EmB4BA;IACE;;EAEA;IACE;IACA;;EAIJ;IACE;;EAEA;IACE;IACA;;;AnB1CJ;EmB4BA;IACE;;EAEA;IACE;IACA;;EAIJ;IACE;;EAEA;IACE;IACA;;;AAUN;EACE;EACA;EACA;EACA;;ACzFA;EACE;EACA,a5BmewB;E4BlexB,gB5BiewB;E4BhexB;EAzBJ;EACA;EACA;EACA;;AA8CE;EACE;;;ADqEJ;EACE;EACA;EACA;EACA;EACA;;ACvGA;EACE;EACA,a5BmewB;E4BlexB,gB5BiewB;E4BhexB;EAlBJ;EACA;EACA;EACA;;AAuCE;EACE;;AD+EF;EACE;;;AAMJ;EACE;EACA;EACA;EACA;EACA;;ACxHA;EACE;EACA,a5BmewB;E4BlexB,gB5BiewB;E4BhexB;;AAWA;EACE;;AAGF;EACE;EACA,c5BgdsB;E4B/ctB,gB5B8csB;E4B7ctB;EA9BN;EACA;EACA;;AAiCE;EACE;;ADgGF;EACE;;;AAON;EACE;EACA;EACA;EACA;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA,a3B0X4B;E2BzX5B;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EVzLF,kBU2LuB;;AAGvB;EAEE;EACA;EVjMF,kBUkMuB;;AAGvB;EAEE;EACA;EACA;;;AAMJ;EACE;;;AAIF;EACE;EACA;EACA;E7B0EI,WALI;E6BnER;EACA;;;AAIF;EACE;EACA;EACA;;;AAIF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AErPF;AAAA;EAEE;EACA;EACA;;AAEA;AAAA;EACE;EACA;;AAKF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;E5BhBI;;A4BoBF;AAAA;EAEE;;AAIF;AAAA;AAAA;E5BVE;EACA;;A4BmBF;AAAA;AAAA;E5BNE;EACA;;;A4BwBJ;EACE;EACA;;AAEA;EAGE;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAoBF;EACE;EACA;EACA;;AAEA;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAIF;AAAA;E5B1FE;EACA;;A4B8FF;AAAA;E5B7GE;EACA;;;A6BxBJ;EAEE;EACA;EAEA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EhC4QI,WALI;EgCrQR;EACA;EACA;EdbI,YccJ;;AdVI;EcGN;IdFQ;;;AcWN;EAEE;;AAKF;EACE;EACA;EACA;;;AAQJ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EACE;EACA;EACA;E7BtCA;EACA;;A6BwCA;EAGE;EACA;;AAGF;EAEE;EACA;EACA;;AAIJ;AAAA;EAEE;EACA;EACA;;AAGF;EAEE;E7BjEA;EACA;;;A6B2EJ;EAEE;EACA;EACA;;AAGA;EACE;EACA;E7B9FA;;A6BiGA;EACE;EACA;EACA;;AAIJ;AAAA;EAEE;EbzHF,kBa0HuB;;;AAUvB;AAAA;EAEE;EACA;;;AAKF;AAAA;EAEE;EACA;EACA;;;AAMF;AAAA;EACE;;;AAUF;EACE;;AAEF;EACE;;;ACpKJ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAoBJ;EACE;EACA;EACA;EjCkOI,WALI;EiC3NR;EACA;EACA;;AAEA;EAEE;;;AAUJ;EAEE;EACA;EAEA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;;AAGF;EACE;;;AASJ;EACE,a/B46BkC;E+B36BlC,gB/B26BkC;E+B16BlC;;AAEA;AAAA;AAAA;EAGE;;;AAaJ;EACE;EACA;EAGA;;;AAIF;EACE;EjCiJI,WALI;EiC1IR;EACA;EACA;EACA;E9BtIE;EeHE,Ye2IJ;;AfvII;Ee+HN;If9HQ;;;AewIN;EACE;;AAGF;EACE;EACA;EACA;;;AAMJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AvBxHE;EuBoIA;IAEI;IACA;;EAEA;IACE;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;If5NJ,Ye8NI;;EAGA;IACE;;EAGF;IACE;IACA;IACA;IACA;;;AvB1LR;EuBoIA;IAEI;IACA;;EAEA;IACE;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;If5NJ,Ye8NI;;EAGA;IACE;;EAGF;IACE;IACA;IACA;IACA;;;AvB1LR;EuBoIA;IAEI;IACA;;EAEA;IACE;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;If5NJ,Ye8NI;;EAGA;IACE;;EAGF;IACE;IACA;IACA;IACA;;;AvB1LR;EuBoIA;IAEI;IACA;;EAEA;IACE;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;If5NJ,Ye8NI;;EAGA;IACE;;EAGF;IACE;IACA;IACA;IACA;;;AvB1LR;EuBoIA;IAEI;IACA;;EAEA;IACE;;EAEA;IACE;;EAGF;IACE;IACA;;EAIJ;IACE;;EAGF;IACE;IACA;;EAGF;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;If5NJ,Ye8NI;;EAGA;IACE;;EAGF;IACE;IACA;IACA;IACA;;;AAtDR;EAEI;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;Ef5NJ,Ye8NI;;AAGA;EACE;;AAGF;EACE;EACA;EACA;EACA;;;AAiBZ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AC/QF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;E/BdE;;A+BkBF;EACE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;E/BnBF;EACA;;A+BsBA;EACE;E/BVF;EACA;;A+BgBF;AAAA;EAEE;;;AAIJ;EAGE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAQA;EACE;;;AAQJ;EACE;EACA;EACA;EACA;EACA;;AAEA;E/BxFE;;;A+B6FJ;EACE;EACA;EACA;EACA;;AAEA;E/BnGE;;;A+B6GJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;E/BrIE;;;A+ByIJ;AAAA;AAAA;EAGE;;;AAGF;AAAA;E/BtII;EACA;;;A+B0IJ;AAAA;E/B7HI;EACA;;;A+ByIF;EACE;;AxBtHA;EwBkHJ;IAQI;IACA;;EAGA;IAEE;IACA;;EAEA;IACE;IACA;;EAKA;I/BtKJ;IACA;;E+BwKM;AAAA;IAGE;;EAEF;AAAA;IAGE;;EAIJ;I/BvKJ;IACA;;E+ByKM;AAAA;IAGE;;EAEF;AAAA;IAGE;;;;AC/NZ;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;EnCiQI,WALI;EmC1PR;EACA;EACA;EACA;EhCtBE;EgCwBF;EjB3BI,YiB4BJ;;AjBxBI;EiBWN;IjBVQ;;;AiByBN;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EjBlDE,YiBmDF;;AjB/CE;EiBsCJ;IjBrCM;;;AiBiDN;EACE;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;AAEA;EhC/DE;EACA;;AgCiEA;EhClEA;EACA;;AgCsEF;EACE;;AAIF;EhC9DE;EACA;;AgCiEE;EhClEF;EACA;;AgCsEA;EhCvEA;EACA;;;AgC4EJ;EACE;;;AASA;EACE;;AAGF;EACE;EACA;EhCpHA;;AgCuHA;EAAgB;;AAChB;EAAe;;AAGb;EhC3HF;;;AiCnBJ;EAEE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EpCqRI,WALI;EoC9QR;EACA;EjCAE;;;AiCMF;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAIJ;EACE;;;ACrCJ;EAEE;EACA;ErCkSI,2BALI;EqC3RR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EhCpBA;EACA;;;AgCuBF;EACE;EACA;EACA;ErCsQI,WALI;EqC/PR;EACA;EACA;EACA;EnBpBI,YmBqBJ;;AnBjBI;EmBQN;InBPQ;;;AmBkBN;EACE;EACA;EAEA;EACA;;AAGF;EACE;EACA;EACA;EACA,SnCgoCgC;EmC/nChC;;AAGF;EAEE;EACA;ElBtDF,kBkBuDuB;EACrB;;AAGF;EAEE;EACA;EACA;EACA;;;AAKF;EACE,anCmmCgC;;AmC9lC9B;ElC9BF;EACA;;AkCmCE;ElClDF;EACA;;;AkCkEJ;EClGE;EACA;EtCgSI,2BALI;EsCzRR;;;ADmGF;ECtGE;EACA;EtCgSI,2BALI;EsCzRR;;;ACFF;EAEE;EACA;EvC6RI,sBALI;EuCtRR;EACA;EACA;EAGA;EACA;EvCqRI,WALI;EuC9QR;EACA;EACA;EACA;EACA;EACA;EpCJE;;AoCSF;EACE;;;AAKJ;EACE;EACA;;;AChCF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;ErCFE;;;AqCOJ;EAEE;;;AAIF;EACE,atC8gB4B;;;AsCtgB9B;EACE,etC43C8B;;AsCz3C9B;EACE;EACA;EACA;EACA;EACA;;;AAgBF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ADuDF;EChEA;EACA;EACA;;AAMA;EACE;;;ACPF;EACE;IAAK,uBxCw6C2B;;;AwCn6CpC;EAEE;E1CyRI,yBALI;E0ClRR;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;E1C6QI,WALI;E0CtQR;EvCPE;;;AuCYJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;ExBvBI,YwBwBJ;;AxBpBI;EwBWN;IxBVQ;;;;AwBsBR;EvBCE;EuBCA;;;AAIA;EACE;;AAGE;EAJJ;IAKM;;;;AClDR;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EAGA;EACA;ExCXE;;;AwCeJ;EACE;EACA;;AAEA;EAEE;EACA;;;AASJ;EACE;EACA;EACA;;AAGA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A;I5C9MF;;E4CmNE;IACE;;;AEtOR;EAEE;EACA;EACA;EACA;EACA;EjD8RI,wBALI;EiDvRR;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;ECnBA,ahDgiB4B;EgD9hB5B;EACA,ahDyiB4B;EgDxiB5B,ahD+iB4B;EgD9iB5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;ElDsRI,WALI;EiDrQR;EACA;;AAEA;EAAS;;AAET;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;;AAKN;EACE;;AAEA;EACE;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAEA;EACE;;AAEA;EACE;EACA;EACA;;;AAIJ;AACA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAkBA;EACE;EACA;EACA;EACA;EACA;E9ClGE;;;AgDnBJ;EAEE;EACA;EnDkSI,wBALI;EmD3RR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EnDyRI,+BALI;EmDlRR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EDzBA,ahDgiB4B;EgD9hB5B;EACA,ahDyiB4B;EgDxiB5B,ahD+iB4B;EgD9iB5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;ElDsRI,WALI;EmDhQR;EACA;EACA;EACA;EhDhBE;;AgDoBF;EACE;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EACA;;;AAMJ;EACE;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;AAEE;EACE;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;AAGE;EACE;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;AAkBA;EACE;EACA;EnDiHI,WALI;EmD1GR;EACA;EACA;EhD5JE;EACA;;AgD8JF;EACE;;;AAIJ;EACE;EACA;;;ACrLF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;ACtBA;EACE;EACA;EACA;;;ADuBJ;EACE;EACA;EACA;EACA;EACA;EACA;ElClBI,YkCmBJ;;AlCfI;EkCQN;IlCPQ;;;;AkCiBR;AAAA;AAAA;EAGE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AASA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;EAGE;EACA;;AAGF;AAAA;EAEE;EACA;ElC5DE,YkC6DF;;AlCzDE;EkCqDJ;AAAA;IlCpDM;;;;AkCiER;AAAA;EAEE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA,OlD+5CmC;EkD95CnC;EACA,OlD1FS;EkD2FT;EACA;EACA;EACA,SlD05CmC;EgBh/C/B,YkCuFJ;;AlCnFI;EkCkEN;AAAA;IlCjEQ;;;AkCqFN;AAAA;AAAA;EAEE,OlDpGO;EkDqGP;EACA;EACA,SlDk5CiC;;;AkD/4CrC;EACE;;;AAGF;EACE;;;AAKF;AAAA;EAEE;EACA,OlDm5CmC;EkDl5CnC,QlDk5CmC;EkDj5CnC;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;EACE;;;AAEF;EACE;;;AAQF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,clD21CmC;EkD11CnC;EACA,alDy1CmC;EkDx1CnC;;AAEA;EACE;EACA;EACA,OlDw1CiC;EkDv1CjC,QlDw1CiC;EkDv1CjC;EACA,clDw1CiC;EkDv1CjC,alDu1CiC;EkDt1CjC;EACA;EACA,kBlD3KO;EkD4KP;EACA;EAEA;EACA;EACA,SlD+0CiC;EgBx/C/B,YkC0KF;;AlCtKE;EkCqJJ;IlCpJM;;;AkCwKN;EACE,SlD40CiC;;;AkDn0CrC;EACE;EACA;EACA,QlDs0CmC;EkDr0CnC;EACA,alDm0CmC;EkDl0CnC,gBlDk0CmC;EkDj0CnC,OlDtMS;EkDuMT;;;AAMA;AAAA;EAEE,QlDu0CiC;;AkDp0CnC;EACE,kBlDzMO;;AkD4MT;EACE,OlD7MO;;;AoDdX;AAAA;EAEE;EACA;EACA;EACA;EAEA;EACA;;;AAIF;EACE;IAAK;;;AAIP;EAEE;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;;;AAGF;EAEE;EACA;EACA;;;AASF;EACE;IACE;;EAEF;IACE;IACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAGA;EACA;;;AAGF;EACE;EACA;;;AAIA;EACE;AAAA;IAEE;;;AC/EN;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;A7C+DE;E6C9CF;IAEI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IrC1BA,YqC4BA;;;ArCxBA;EqCUJ;IrCTM;;;ARuDJ;E6C9BE;IACE;IACA;IACA;IACA;IACA;;;A7CyBJ;E6CtBE;IACE;IACA;IACA;IACA;IACA;;;A7CiBJ;E6CdE;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;A7COJ;E6CJE;IACE;IACA;IACA;IACA;IACA;IACA;;;A7CFJ;E6CKE;IAEE;;;A7CPJ;E6CUE;IAGE;;;A7C1BJ;E6CjCF;IAiEM;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;;;;A7CjCN;E6C9CF;IAEI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IrC1BA,YqC4BA;;;ArCxBA;EqCUJ;IrCTM;;;ARuDJ;E6C9BE;IACE;IACA;IACA;IACA;IACA;;;A7CyBJ;E6CtBE;IACE;IACA;IACA;IACA;IACA;;;A7CiBJ;E6CdE;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;A7COJ;E6CJE;IACE;IACA;IACA;IACA;IACA;IACA;;;A7CFJ;E6CKE;IAEE;;;A7CPJ;E6CUE;IAGE;;;A7C1BJ;E6CjCF;IAiEM;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;;;;A7CjCN;E6C9CF;IAEI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IrC1BA,YqC4BA;;;ArCxBA;EqCUJ;IrCTM;;;ARuDJ;E6C9BE;IACE;IACA;IACA;IACA;IACA;;;A7CyBJ;E6CtBE;IACE;IACA;IACA;IACA;IACA;;;A7CiBJ;E6CdE;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;A7COJ;E6CJE;IACE;IACA;IACA;IACA;IACA;IACA;;;A7CFJ;E6CKE;IAEE;;;A7CPJ;E6CUE;IAGE;;;A7C1BJ;E6CjCF;IAiEM;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;;;;A7CjCN;E6C9CF;IAEI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IrC1BA,YqC4BA;;;ArCxBA;EqCUJ;IrCTM;;;ARuDJ;E6C9BE;IACE;IACA;IACA;IACA;IACA;;;A7CyBJ;E6CtBE;IACE;IACA;IACA;IACA;IACA;;;A7CiBJ;E6CdE;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;A7COJ;E6CJE;IACE;IACA;IACA;IACA;IACA;IACA;;;A7CFJ;E6CKE;IAEE;;;A7CPJ;E6CUE;IAGE;;;A7C1BJ;E6CjCF;IAiEM;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;;;;A7CjCN;E6C9CF;IAEI;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IrC1BA,YqC4BA;;;ArCxBA;EqCUJ;IrCTM;;;ARuDJ;E6C9BE;IACE;IACA;IACA;IACA;IACA;;;A7CyBJ;E6CtBE;IACE;IACA;IACA;IACA;IACA;;;A7CiBJ;E6CdE;IACE;IACA;IACA;IACA;IACA;IACA;IACA;;;A7COJ;E6CJE;IACE;IACA;IACA;IACA;IACA;IACA;;;A7CFJ;E6CKE;IAEE;;;A7CPJ;E6CUE;IAGE;;;A7C1BJ;E6CjCF;IAiEM;IACA;IACA;;EAEA;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;;;;AA/ER;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;ErC1BA,YqC4BA;;ArCxBA;EqCUJ;IrCTM;;;AqCyBF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEE;;AAGF;EAGE;;;AA2BR;EPlHE;EACA;EACA;EACA,S9CghCkC;E8C/gClC;EACA;EACA,kB9CUS;;A8CPT;EAAS;;AACT;EAAS,S9Co3CyB;;;AqDxwCpC;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA,arD4a4B;;;AqDza9B;EACE;EACA;EACA;;;AC9IF;EACE;EACA;EACA;EACA;EACA;EACA,StDqsCkC;;AsDnsClC;EACE;EACA;;;AAKJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAKA;EACE;;;AAIJ;EACE;IACE,StDwqCgC;;;AsDpqCpC;EACE;EACA;EACA;;;AAGF;EACE;IACE;;;AH9CF;EACE;EACA;EACA;;;AIAF;EACE;EACA;;;AAFF;EACE;EACA;;;AAFF;EACE;EACA;;;AAFF;EACE;EACA;;;AAFF;EACE;EACA;;;AAFF;EACE;EACA;;;AAFF;EACE;EACA;;;AAFF;EACE;EACA;;;ACNF;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;AANN;EACE;;AAGE;EAEE;;;ACLR;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAKF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;ACrBJ;EACE;EACA;EACA;EACA;EACA,S1D6gCkC;;;A0D1gCpC;EACE;EACA;EACA;EACA;EACA,S1DqgCkC;;;A0D7/BhC;EACE;EACA;EACA,S1Dy/B8B;;;A0Dt/BhC;EACE;EACA;EACA,S1Dm/B8B;;;AQp9BhC;EkDxCA;IACE;IACA;IACA,S1Dy/B8B;;E0Dt/BhC;IACE;IACA;IACA,S1Dm/B8B;;;AQp9BhC;EkDxCA;IACE;IACA;IACA,S1Dy/B8B;;E0Dt/BhC;IACE;IACA;IACA,S1Dm/B8B;;;AQp9BhC;EkDxCA;IACE;IACA;IACA,S1Dy/B8B;;E0Dt/BhC;IACE;IACA;IACA,S1Dm/B8B;;;AQp9BhC;EkDxCA;IACE;IACA;IACA,S1Dy/B8B;;E0Dt/BhC;IACE;IACA;IACA,S1Dm/B8B;;;AQp9BhC;EkDxCA;IACE;IACA;IACA,S1Dy/B8B;;E0Dt/BhC;IACE;IACA;IACA,S1Dm/B8B;;;A2DlhCpC;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;ACRF;AAAA;ECIE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACXA;EACE;EACA;EACA;EACA;EACA;EACA,S9DoZsC;E8DnZtC;;;ACRJ;ECAE;EACA;EACA;;;ACNF;EACE;EACA;EACA;EACA;EACA;EACA,SjEynB4B;;;AkE7jBtB;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAjBJ;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AASF;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AArBJ;AAcA;EAOI;EAAA;;;AAmBJ;AA1BA;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAjBJ;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AASF;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAPJ;EAIQ;EAGJ;;;AAjBJ;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AASF;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;EAAA;;;AAPJ;EAOI;;;AAPJ;EAOI;;;A1DVR;E0DGI;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;;A1DVR;E0DGI;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;;A1DVR;E0DGI;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;;A1DVR;E0DGI;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;;A1DVR;E0DGI;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;IAAA;;EAPJ;IAOI;;EAPJ;IAOI;;E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","file":"bootstrap.min.css"} \ No newline at end of file diff --git a/www/favicon.ico b/www/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b20cfd0f056c1c9d43100f612f4319c66e2adb94 GIT binary patch literal 2550 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 literal 0 HcmV?d00001 diff --git a/www/img/exclamation1s.png b/www/img/exclamation1s.png new file mode 100644 index 0000000000000000000000000000000000000000..c54301019c0ce46b45da78b36e07b3c1649ce2ad GIT binary patch literal 755 zcmVEX>4Tx04R~2kiSa9P!z_0siH-6QXE7ugKNdbF1q*! zgF~UF5sXf0l43E5AxSB|fp4M@(?Jk?17ASF+3!XN2eWwLw+1hyJC1WiP(bW=q;(KM2dbH#qfZJfE*vroMEHSM%JTXCaEqP<19{VO~^V9f-Tr zDmN^#cI&yv;s>!ErCB6?5^qOoWZ3MwX)+0aJk4#E{=6}D} zKF;e+YkignMNqfqq}FHz?~kzJ!|F3ET{mR4f4{9^rd!Ya^Nn9}8c?bufFK_L0007F zOGiWi|A&vvzW@LL32;bRa{vGf6951U69E94oEQKA0a!^yK~yNujgd_#1YsD*fA7q+ zmi3iFam!bK^Y*p!>A-HU@#5*Kc+O4)F7Mp6zwn$~{I`_9Ze z<6x6=;CK2z|9+R}dEgJk&tdbRe&@Z*oXDhp2^*c!laJG(Oi(n1iae&7GZSg|TUcv% z;(eFx_{50ug2@vPZB4=2I~b4=*3Ix`j1rOr<3uRaNdJp>2w=c^Xzyzj3PlL`C^R9( zeE@S+jOBY~0z7TSuN8C#)BzZEM;BoYU(kw_}omFO{85Dc0Ps=8De zMY)>8FaWGYp~nk;t@TyjA(2%<)|RHZF!Nj;4b?>^d^8#tn^!a%O(B`x1_PEvm@43) zP|T8~8HGcMVE+413-v+Vx)lfpXyqJ@ujmjm>wpPx?T%XBsLlnG&-T4`J!?g_7`dGL l>siUYnw;0o$nG-#=MxUJj-(sjOYHyv002ovPDHLkV1lNLPyqk{ literal 0 HcmV?d00001 diff --git a/www/img/exclamation2s.png b/www/img/exclamation2s.png new file mode 100644 index 0000000000000000000000000000000000000000..e067dde1105c085baaab67bd23b8b4fcabbefc09 GIT binary patch literal 703 zcmV;w0zmzVP)z3MvZHEG!%hjQ^Ryh9)^o zW)S9)W|(&{pW*H2#|(e|{$}{~`y0dKdyn?cEx+S};)2j>@eW->qjE+hUuC+@Vi4w) zW|+M6&U~g`F%n`S<#G{iH+gkKSY>hdCp*v z5>jR8-5AC2{>w|S7!%NO-+p}l^XSgQDXZIF6@sk`trBw)78P5^!^_Ky5)+=27*wQ8 z7^)UJGW`DY6E6Po!-r4bzJ2jpTKD)U*nr>);R11K@qT7Tc9bYebnj%)l(S+en{A5{ zZ{NRv`uOe35AS6SPmeN&REhw-@OLFIA73B`CnpQC0rvWl3*vp1oBKYyqeP=$ zF&__5fdUH)%Vm%OjEsy7rkWlM62giM+m6ivYW&6U8xoR|K&c-<=YPjY%07iWQa~G) zF*CAkXJGo@0W|PE6B8rrzkmN3IoWw@zJB`{#=^>CyQTljUxJy*J)3ghuA8a1xU%bj=O=;Mp=hO(lB4y-3y8tv=0 zR%6_!o|mi!r&$Mk9)E&C|4hs$OCki`dCUB*m3Lx*=3r6OgGy@_Z5rac-uLZ7For=}7Rx}qSInwX5W~(WFsNJOnusJgsa@w9k zMEngF{5~!k;);FE?twXgyXmBUN%my~B|)P0l1;G9nFg-b2MNNF4t|Qkz;0hl#Q<8} zmrxOfdm6K?lu0r$@qi;6av(2#5mffRQhl=}h*|>gpS;3#oIkCO%zUijqR#F(1B$FB zyHf3tW-&njm(e%?0w0(>%w4bRQdO|In^5AzQ#7NoQY;IIR4mzBQwGZ&HYjZBgwNl7 zge?(;WgxlFxSO6G2{M|GdW<9?i>8?mNKpiWuxrgqaHiOxqyG&EBG~~^;7JFINiag% z56@d=Q~9}c5XEkq!Y2x1qarJQ0%FMmp;4!;-`h-+S}k%A|ubaq3){2jR-JH@AZQhippJ=9MTUBw)S*cuU)xYC2L(aBqQ zxBtWfSqF%X*4COT33|hUs3g0=A{KzS1(3rBkc!%81gY2$SoyYCQ|6Lb!>RbMJRp8o zMikJ3CnDDiOaP!cuFx_8*ckxw?g&_!7%(t_*ef}^^eS*>xxFNVnc>Po|IYBG;;O{f zM>)XTPGGB_vYJIH#HZ&@hPzW^S-|&^YGfERx;Y}Z@Fs6NSOq}aB;cxTpug;}Gg!=O zm`9MI8T04o<(uK|^!aSKFT)k>Rn_jtQl(T`+*EPj7;rUvKzq_`gSEV#PNq|OM%~}g zm6*x_hNN?Ke$REp_>vKct+xRC+CZD!QKD<6n#`og0e{!Z6#6>kMAT#tt6b%WB!|c& zROkWMbR4j^8H_g<@|tB?plXCDiM1P%KK)|edu~9yCVML`GgkCSHZ=iq%D@(07l{m( z74=x?ihi#!#$gE=#8Aow-d!$mz~P*)mbw}7QggK0O|up^{2^F^rF=qMTE z{D4?tQWo@x_#=-I*c-UUgMi&3Fy4;G)eW-Mu4q?dKkfdf-}txo8^D47 U5nB&I2><{907*qoM6N<$g3SC%2mk;8 literal 0 HcmV?d00001 diff --git a/www/img/exclamation5s.png b/www/img/exclamation5s.png new file mode 100644 index 0000000000000000000000000000000000000000..5d5f9b3a91323aafc4a250edfc66da45fe577b45 GIT binary patch literal 686 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 DEKu5( literal 0 HcmV?d00001 diff --git a/www/img/kafe_in32x32.png b/www/img/kafe_in32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..d83e644ea7dbac6733c781d56217156c7defa6b7 GIT binary patch literal 1884 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 bZ;}53e#$yd@!m2*00000NkvXXu0mjf%l*G_ literal 0 HcmV?d00001 diff --git a/www/img/kalendar16x16.png b/www/img/kalendar16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..2d0a5f893cc7b9072ce267ac3c7747754998bdd6 GIT binary patch literal 684 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 Jmvv4FO#oNMz!m@i literal 0 HcmV?d00001 diff --git a/www/img/mapa32x32.png b/www/img/mapa32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..14e9f9d24a479beabdebcc16b45be540f58b671c GIT binary patch literal 1574 zcmV+>2HE+EP)t^Yfv+@h!8?~EDJ0w0?RH7yLa#I-qX3)L=hxhsm`5mzI*QZzVH0* zc^?LTrZ+MSS?d#`UsNj;xilL_#b|c950_pxm3+~D#XiwEj6aoE=47p(6R!P)zH(y} z8$W1lUtWC4)G{dm+4JVJ35Fy?N=izaN~y3XH`WF|Fxd0WwaR&~7amcBTB(GRWn~{i zNKO8^i`i%U?7kagExC7@I>BH_H+OVczCZC@*9ZVZQW86N-U35nq9KDCWhPLq(P%Ph zQ96~N&=9Sdm=Mo;%iaR{xk~oAGUP-*?;ie>Sgi)ZoJ!804~yP?AvLR8iW3*F&s3>Y z8B#S=6vw|jTJYZ6B}Ya8Y~8*i|FOr{9F{+dZUpm95ImhYs0c!vrx%t02MLYTG3CW) z5ae{re{QlnV10Hy5|=&#;r%j*=gz_q9xBJP&R&RyXi?0d*P_K^##|31%wy`~n359D;yO#}Iax-UlH-iM!94@x;M8OxK0W zey5VO*t0ZhRF{4`8o7x4FfEl?_hToX zI%Sq^h6Im14g?AltWqLc6D$uz$$sObdYHmE{{f`5nm6GUXN_!R4GAFmhJ1z*80@F5 zpd0kua^_T~YDvlBs4-{QZ2?GW9p8+d&N>h+A@3wCV2&y?kXPMk>9A8%Sqd5VMxcr{jV_*~j%r?Q)K?-JctagLj1zpHrAT0J^eZm+~Sh z)HN}$tCr%VA_+504wN2f7_pLBXrFJ|HWMzJYmxzI(yAG9OnaO$Ga=Z-t)iX`UOv=> zCH4KoHbn)=sLG6hw|8jr0i<={xzLMDp|1`*RV#2o5sRpPH_G?cg7Xs8>NVKCF(b1UWVPoL;O;h8RM-<*M_X~FWhn*mb2cD&%M z#T>5{=cj+|KY+9l6$vM?L^Rc3Bzzn(@&ek~?se<`p zCk(^}4_LZih@*|oEMXlCQ{|c~|8=MD`lfW-01+Y&sVP?mbPy)iH=z@h*%U+GZQsD0 z=CenYO&CByM0xN?gGfuf5b08kSW&hYL=~=hqG9n&L$?qkYYWxge``yxmk2yRChUX& zW_$YNX_Mv~kjn-|H7dM?q+YX#kt(oyr_eFY-m(P*TNm;0F8=^}j9cUdLn@&Ej7sNX zl-bw8!Nm|REM`Joa7O?OE+fELQa?;Y1RdQ4)QHDe@-9tWDc@g7X zDR>Ity9t1vQ|Pgs#jbgp@c~|{8bG{O0ey&KSce6$xOOj)o7gAPv!DnG=DJ+Z_w`sv zl+wlMsee56mvnS63zoTB-9Oz6q}z;<=lS|JQ)`{cXsmB-HP&@?nlDF2P7T%T^@;IR zuIhxu*x1+vj^h%kkDf}P6sy(LF4_ki60CG&YOwY9*U=dDG#1q@^)=PiMpLU%908EC zcu5Qm7)^~DemZ;FHIcr)G2OFpAw$7pBrw`Qq0P{FC%m4rY literal 0 HcmV?d00001 diff --git a/www/img/muz32x32.png b/www/img/muz32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..33c3576f02562391dfdf6bee4511190ef171af39 GIT binary patch literal 1257 zcmV=P)6LR2tzlvp^^!MN_jat5h@}DT6)`id+*Ne0<$8}nv19TdhR*rd;HFq zbH95q@UR611<525$=foSESX^#4NcQhhr=<6`bLr@Pjq#4wRqwW^F&##R_{WA%2B{) zr zN~L`$#a;*i+yG#uNUzs_#tA@7Ow4}d_$UGZAE_AjWh6jn*AO(ebSwyf`ljCA-j_K6 zh>eXcLp#rTNgWIaa(05!UjZcPfU25SxbV|;7`M*;VJ_~G9S?=RTcX{ z;w7A$XOLK}Hn1ZY)1(D1x88(`%4V3Fo?!tR5P+5wfQX2Q?OQg4*A*X3UQ~}kzq*DF zI8Fo+BUi|I{U?Bu3bPvz-!y06{w>ro|~x>Z)o z=i^C>>5LesTVBto)VBZGW9J;8ukCQs3V&JcVpaq}Wj_^GaLQeu9sv~PZNv9x#$7{M zSof%PilRH~F7-sEWu3Jy3jo`GuE~5>ty13N@jx_d%+>=`e};9vW18q4C+>LS&tri4 zbJ;65t`9Mgb_+1H6*)lRaWM#l(r)j-e3hsEJO(fi9nZ&ctkk)4ns)9V!+GqGzJ15E zHZ-zuaM=JVzxz<0vUyDpdQ>i;a^-xpUYok-7{NI};oyz+G7g6%{MjL zc~CvGqH~0n9Qjfe^CKq!TfS*q?YBClBsv63nUPOnc7_6f+c>Os+y`GE0B2~JWCSqa z@PH zfdygD0OP!TFu+5{K}dMPs8J01dk!Gc9I|C-hN&gShTp&XZk)kwfLG3SKQHoCo<$BK zkPny>aQcJ*2@bw82M9zCCxF$8!~H27Zky3<=>dK8H#?q2D0#o8hE^;Iu(RHni1P*C zBO@P|;12*SC=adA0>J-sXU5x`GHxEtq8LrQDF%>a)H02E=_+Lo?vb^%B_KeU_gEvsggmKy-c>EF`A_PPMk7~~aRDhLJ_!Ja#dP|Q42^3B605pD=PUdU0gu0I05nAcJ$0|% z{I_oJU!|EN^WFk&`Q=?gU*)H`xBLZ+FW?M-A?-k0Ozq@^@yOMWk}obiSgFl?47W4lvlT(OY T-RdqP00000NkvXXu0mjfn7274 literal 0 HcmV?d00001 diff --git a/www/img/navsteva32x32.png b/www/img/navsteva32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a33a017df87fc0e0d1fc3071512580043194fa5d GIT binary patch literal 1184 zcmV;R1Yi4!P)k)(d;NzTk< z_sluJId{&?2q~q&Jrr>t;QtF?w?Du(fvTXnIWVs$yFH4ng?f|rHx~vl0PW;$)>Xrr+@A@*povG6?k6g+u0sMb_y8WZ4j z;=$ftSTA-XT2-B#Q$z@7D1g0m_EyN?Ga=g8ulHqTVSL9JUq&E08j7O8+ux6P2Glf(zmt-n zrlslb5uBXF<41qdQe3WV96B^)2C$9*r^8zPv`7XWdE-s^tycUsI*OFDXOPa7-z`Hi zG3d+8GHm0nT|@CJHM?WH-X=4EX9;j55&&;O0mgUkGEyDa(SdZ2G8Zxsz|hsJ=qX)~ z0LLpjI^He%;`6;`0GkNV5(&VKib^Pjh48ps$US!!x9V8x8}P~%pt~FB>VoumaO%4z zxRa9+3tyd$FqJXXcxqc5o0F7+`w5Gi)!s{{aT` z*608yDl5u2&IMokieYVa8igWb`8|jPypJJC2)MZAMV^-_%_dl$C8>&h9hlx9ODVZ;XO@UqmB9*jR}A=E)3UHqN`bVwseuFpm)A zX?7c^$G8W64eLqf5aMA%oZxVc$=|~aUYagt&wPH&BKr%5vk(I0f0000&)sd(LGL;3;jo zXh2tnmWQ?xEzb3725ktf3(eS6T0Nq*2GdwLi7|E=!=0RS0b}<#Y;$U>9=n_vnlP*~ zmK+@o3Q*R3sT?QNTz&i48*82Y|x88Tkm1q4ZsS*3A0NV<CZOBqVp~`pzh9nM^zrQV_%K){yAOlHJx<91vlC{;yJVp|;E=j=O#n3~pv%6%;X>8eZLi4xfFAS|m(T$Cc%K!iX07*qo IM6N<$g7GwqZ~y=R literal 0 HcmV?d00001 diff --git a/www/img/pneu32x32.png b/www/img/pneu32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a49155c5b1d3a3677f2d0376a404b223231e7740 GIT binary patch literal 2590 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 literal 0 HcmV?d00001 diff --git a/www/img/poukaz32x32.png b/www/img/poukaz32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..aa42c219fc9a6ebd7a4ab528bf3f2f61700cdf9f GIT binary patch literal 1827 zcmV+;2i*9HP)o~0-L6}ab z$|FT>gLOsfa$&%eovU?wUdhWimyICe#?3uZ_ zclO--{eR#8`|i0X1bp;8DOQ`($WsDf13_>wevkm5^9#x+R1F9OKs5$c8DrauUsliH z|1ijZe=hB@78dQjZsT)gst@%Xt_`Suwzud-<%RDJU_X$hWN%t05~Z7`s78KHxQ&K? z=5`Pnn6(XkM`{DyiMpF!Quci>0Ov2Ww5&VQ1n8r1bd6xxu7EMhsELx<3)3LVF)+cp za2RPiP*{iF`dZyT!s_N7ymlwZ;PX~3vrH7+b`^u)s4S~MSk`?}`j&9X`-oW1CL+bu(0vLGStmT%;LVqVkKpVSUu+>*=OtkJ27n@|$ zxg`~%CC-7EYi7;?z42!p;z>;zW&7qGO5F+4zuTuD7L>~-W?P9bTfaef zd!P4P{|wi8ed(hd!b>vf>~lswc@l48=m%ka#&}Ripd&hkU#o2X3yP8U(rg zv_&bZ;sBAjavsiJqF6X{0MC5-6do%)i6!}6<8=@H83zhe7?;F=$iEleZ#0bQDjqIA zsGgh@;EP=r|NJVGG@cpoc@II(G=@KQltVVDcy#fHh$f$qIg9)jo+lD7N8Va|)z~;1 z&{0z|2?S}|X;p5iGKrxqLQ#4KC`ez8Kp3I`kvYO& zQ6awqT}{Wmsvk9rj;ik@1vtN5bS$XK%ofdDF%W`q4ihN+<8wvJ#VhTbQNOA_8aOWN zIDq)MU~oB$J5hUVAzPNbGSLZgx<*`W%^-grzIB0RO;InPdEpx2017aqX5(nv zM*QZ^hUB8L^^XEXIy7`m%|rYQoL08&IF5N--y`y#{qc<=w~C zPoeIW#F+m3q*yZA!Mu1Pd*1k1r2bH*L`_v_iChFO_W=Ba~b+1UNAO0(Y!Fo{<6E{p#5Z4uB zFC#*po`cR$JRbX3zA9dVf5e37p=>*5u!qIIfJ`1 z10v$aq}nXJ)6*r$nK|fcb$Q)G%1>AQPHRH4T-H=nQVvi|K-xckza{YDL*i=5O8>lg zeU^=K2;Yz+c%Q((9z>W#oUd)#7>~q6m~(P@=0jf3pz=5uZ;aeCB{Mn1N)GXt(yDA5 z0f!iLgc?d_!7Y2TD2%V9>WDER!kRw=ovntrKbm<;0LJ*+gW?J~jlUgLIlLSSd`<@# zZz^J9K{tYtB8w8wTyc|N&C?6=c;SqZe>fNo0Z>umw&$bcoWtX``?s$? zrX9apyp#bFAt-lZY+wNDXegM;!o_FiOX+=iHh~79 z3=aium#(vMal6-J_iy9k&6CAR1;A)EqvuVL^U2+tYBKv<>Tchdn=YrN^ZzRpTt5BX zXzL~4o}av@zsK*IgkoKT3DFIKx95}GhMpnHu|zHhYDU-fSu`O2lxG5{~#>j zL#QQrtHKo{9tdCSsQ^S4VVZD^-ZY)uSUHy#b-I}2{jNY?SRnjDUiAph{||(oab0;v RoznmS002ovPDHLkV1kAod0GGf literal 0 HcmV?d00001 diff --git a/www/img/prachy32x32.png b/www/img/prachy32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..4edf814c26d73d2efb9a1c246be3662c96a7cee1 GIT binary patch literal 2512 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 JPDHLkV1i^CF2w)< literal 0 HcmV?d00001 diff --git a/www/img/pracovnik32x32.png b/www/img/pracovnik32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..e5af3786131273b3b78df4cb790a8ac91c0191af GIT binary patch literal 1956 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 Hu0mjfNyP^I literal 0 HcmV?d00001 diff --git a/www/img/sipka_in32x32.png b/www/img/sipka_in32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a4eb4aa66b3c4614b10c609925508d2f7db97bbf GIT binary patch literal 1604 zcmV-K2D|x*P)|?4|E;A|9d+&Hk|>#l0Q&QC$`u^_C8k$ zGLAw@1O@;RK~n^x=4d}(^q=yp#aHJ>&s}XAfNSSI4*h~ZR7|=(wOppl5W^8h&QWlf zP`7}`fM&w7<7E9(_Q`BHw{Py`~xT=6!sP~sjpHt-D#QO2*K466F|g*Fk{7Y3x!hd z3BTYEUw(gbscA-ZW$c4`%evORg>0r*a_J6FX(Y8m!qH$@2s4-fAwoUr70WG!$4eb; zduQJ|ef?k0A^_;zxwR+RR(`<}fe26{#LQ4kU}h+az7aobt>Fl>FsJhmZrm}yy2>Dc z2&h?LwN?WF+%y(7V_=DqU;Je3`l+eM-u&5~OP>R9->%1>n!10(P+%<}jEoW#g`tI^ zn4yH>3d3ba(sPl}0uY0Uz#M_L#E8s^aAUQGIsglc&;p?eVTj>hU3!0UbaLB?-Fq&7 z#s@-X_)Kt_;4mW-XYa_h{k< z5LYoY12-zUE#;m~hrYaPdjS9xfClB-iZl{BH%=X zHT4((iU=VL>hYfyAp*zNB00A-I`j6~fsvPn=hu2b0f2;|ZA*H_fZzxdb5uu11WE)6 z*G1A%4W`xt6A^00&~i|Z5ykq~B60mA7KjNf?00-^%aC+dAGX#sSO|>4auA?y5ebn9$!ph7UlQ;k4_WePxZOg`2a8J1}GyyCG zL>7QWXbp%WIt>WPrInAyUw^0X$nHN(H*F-VblvkSbdTAXFhI>%SeQuZ1Y}l%*_jik`u6?!H|Lr@ z6HbntoGDc+$ExeUFjyCOCU!m>cY9(vxHxg-t!=|U`t_MRb}u;h=IBhdrF^V)efwZd z$cxP%shh#2Q^QC55AJ?>?2g}zCQgjbR9ec%Djn^Et75%u-Ch}c^?3i`7x$dJYj?x( z6QeWL*7C8oYGv!h;gKi*y!++%@c&pn{k^w+J^v>pL)S%`%=!QT0000%abMZMe;`uC=>xJL}!; zEPi(3vSp8SbPcrCOgnUN_}tJP1@N7o2bMhC-npy6xz^_T`pqq+`hf$(9}e9S0M9JE zfAM3TUA;A`vqTgRrIz|>n_J2adk*$-7B+Vj% z6Gc=Iz^RfX1(KvdU6M3TFV{SKt9JdZ{Pg`LE4v<=*SWhvXpI(8b;KC(;_!t8M2RtC z7{@;y*>>WS3(rhh2%fudMaSyS?*19xw;>7$U=#{Pip6s7eFGIves*ccTSI4_er52; z_>_3ydrMZ$d!(zo?=I)sqk&?G3dKS#s*0I`2%^TRPcQZ!9Qxy{ zmoF1SN(?D!xVkZEIzbw$q#>Z{7#SP;9dHf6mKEQaxuU(RcW$Y4Z!}1JlKaOnQJnLr zQ_O^DhGIDh6^j83e4#*Dh00h35Hu&Lnc zQPpL9m+WMSU^z?FdsGF>Ph@78IEYG&Avc(v4hi_`M9vk(oM8s40q~fBGcL|&fL-P_6>!euRC7Ri%@EDOWdHw{ z4!kt5eb^_3$DUZUc%V5cF3dO}s0dih+-5P8UceU%h;w!&Br!%}o^m>I8BIKC2!ynn zXGWHaAXIJ0ZYo4C^uK<=d%yb8o_qUR3dKccR}@1ri->cO=Q1&Jboisc_8vdBF@$t9 zn1Myij1U4LO*1_(z+wh88si}lsuPu)3enZ_yJ~&QhWj3Tb8fM`&~h@WI$Yv0u8>nO z0w+cVdWcxoD9Brzp-`3VV=c#&^Oh*LCv=GS~5)?3DW~tbblxiPnt(*4R zU(TFNr>q|sICEm8xvp`0+w9g2waz!9LIxuv#}z@cV9Y9&=lf!^bWYujt^3cON~f$R z{L?>*BuWrpPgLEyMHm5L+Xcf_e^x)GZq@t%FsK-c&!Z1r{U_}aI_Ed~& z&>v6;Ap&0lQ34}ml!M4Jn-k~ecDH-y{qyzR5z=yX;9R&Lhu?Sjo$sLe`FRTfuuvux zMFBw&AdyJO!C){`t_DS;Q5Gh0V#%fJf1Ncjhxfz1eRq%T#rL) zeO(kk&pJJw7c%HiqtAlDi^oPrMu~MG#t{*QNxLYUPT}g0 z>eP#;*Zq@&SN0fim0l@;h$%=*D$YvSR~8Tog-|k?>?HF(FgG_hJv%e=;nsfr!!B1v zhi+3qSq0&=P*AWe?Jf(@f{aX0mPuQ*N|IHzM#^{hQ1v~VnzwI=n^H6-_4dWoJO2cb zpnh+uo}~7^SUm;CdNb5zWr&$+So*|+`ai(7#nYbh--o{d%Cazf(zeb|00000NkvXX Hu0mjfcO+xJ literal 0 HcmV?d00001 diff --git a/www/img/tablety32x32.png b/www/img/tablety32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..11b1a7707e58222e9bbd079e32c92e901de00abe GIT binary patch literal 1965 zcmV;e2U7TnP)O@GoW_jk7^7~S8SFRMGc5m2yH2}*Sq`P_vgpw`QCkRm4wnGOZG`V z{q%aDAFt2zyr1X!l#PsxC;$+FGMnQ#VB0pBrU|;PgQjUPF)^WacXwyY*@umej>AdtOo-8!>e0EVMvU7P~=;uHuM#u-2T z`7PqvFMq36R(wwkg+axoMpdSxz z+$h|ZorX9%L$vKbR7Hc2gqAH6@%G%EBgV10YMO~*49>IK>%KRdFgdOX{?UD7^_PN5*ite&2a*A@H=!28VjYr6WYtE<5SkR+)DfCn?mlGq2Do11T) z7hpFY-VQKO4NMBU7T{b)07?|xh2Y#E3*aXsk>E4&_+zK;-!i=X=9^!M$K#BmfBeBIW_glpFz=SFF$qd(Z;+&kI29 zZ@{*+AWOjtj77I?h3Frj1R)fnuwtIN34q4o;o%|N`1>eCjyfm-kmnHgzW~|nS(qAI z*0^e|H7~#(U;>)(Xd~xq>VEksi|^RsnibXUX2v;H&{a8Z&hd5(b>IS^4!{*6cer`! zJToT8K+9%9^Tizd)bX2=cm4c>c>$(OB+SaVufq9;h zxX`rR%XGX@h)OCaGn+FPcx>P=EI4!kWM+ZjPQ#pxcGC%f3p~f=<4p43*w{bqTos_N zw>MBzS2whD>C*3@z+3=y#kUd-iOf^EcKj%>>ekYjRKqci z=Hx%EGgk$0^{{8px|J(e4q&1YDb5kXO*F+Yb45ljKn*}<{A(V4Y%L232KaDiNhsD5 z0>Jy`5g;e2IA7nEdfR?}K>&vi9U{@afNAvJii!$1&OI&6eUiBV6XziC>$MOQbnu}C zWbB0`#@u3t0H6s9WKHLA>K*gP3j(0FZ{NP!hK7dWL?W>Wg;okPib-?>^8ltldM_7z zdP|@hPxp)H27I#Mz$kPqJY2^YOwM5}C;HR2WhR>6GqVcXtZ zoO=N12IpAsb3f~R^Vw%=qhWtQaKNW$xkO&TQ(Pe;fMx^Bihk10`u6wjqYDP;@9!7z zmgI`=P$=XT9F9654HyGQ4nJ{r@bI5jO&ou>vnH}Cf+@q7PZt1Cv?h}<6tR|2)Yu$h z;DHtYvU?T`K&`j8S4yYTTWf1;x1&3jqX*2BCr=I?IB?*}!NI|Q8+lFKS}#5FKr;H9 z3ROW1WI*It!mx%IsD>;?!mR0lY~%>wuA4q|4wVH!ZPTVr;+ZpN6ztJVCL`eOEfgcw zEcXr5phBwWhR91*(WsCOJxC&0CAAe6*Au5 zJCr&-AN*ebMbh`HJCgAq1q6I1=d;Yhs)(4Rer}i+|0-uc{OBjnF50tP3($PZLR9eQ z0{Fpu!{G0jghCIcLfday9NHilnq*+8nwYe5rad({>HMxjVb48%+Oe+%fEvkPngb%w z0aA+JQ5O~m#3k(!_-=sNzOOVm`AG%_lR>!f(F~NH>(>I{tz$(Pu{h4{tT>5dJ#hR2 z*s1_l1pmD_odf&wjs6#nUEz0r**NdQ|4aJ@Sm*{_^vy{>00000NkvXXu0mjfzdNdQ literal 0 HcmV?d00001 diff --git a/www/img/telefon24x24.png b/www/img/telefon24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..a9999c9295aa454f4eaa88f183082ec4159b641b GIT binary patch literal 861 zcmV-j1ETziP)?&C`cpPqC+z+br*(d%5+2}AZB3~8Dg1nnojQN<~^N^ z?`1SSaCzsxd*3PaAEM8vA9clGwU^Coc5h@3B`vz3ksl7-wja0Q6)epUx2is|gN)|;j+_>@(h zv8vqwR#m+>ZoRhOcm0S}ok`43Px&TD%ukO47x@2n!A0Q>M9D(#FtD%%ST=(zRZM3q zj{BLHfo>!68j6p5`{Z=|s19_+$iG;W8;^chP`@Ipj~{Vkj!LqSi(A!F8(Ww;eoBUF z4KJ8nT6vX#sG1@Dm_?U;{Ns+06&@w_@ zsC+drBqy!I=#D+|vZqV_So!O%XGLVe0Qt?B&=jMK|E!Xmzo~`DHil{qJrnBJ!P=^K z9`r;k5%dLl1Iz;Jn^np<4o~$J-`u&*)#`J8+di;iy|l7~eRKXiTL)&nUi1Sn(uopQ zm3pnghZ5$?Lq{0ecaWy(=DVM7QFUzl_PJs@J1U;Q01Ivp2|D^41gF_pW3Ap03mS>` z;+PHlUs=^uX?U_?07}D?6=1?+!@HQXElkhOK6?6lF>mYQgd20Cq9qHtDOVF@i)~tg zZ;R>d#X!k)h3ASNTmhQg3d=-kcrsWrUAV3RDPXP>yIRaCiztc)P5~f3Ll~xRl?L$!0C5sNz&DwuQXn{h zBSIbCa{<8t+|=dO1%wVj2hjq=-UR>$5i5XeSpc*L8Un=Brnm%NbtZ3!dPe~@ow_AOdiofV;kBqzv$p8t*P;-*F zhp6D4scvu*&k+xi5hJ$&5>KY)HZd_o;qIs-t|b%i`!qn}Y1C8@wP6w$p(m~&6Homb z@H~0de-QUJF~@r*BmYk5tHTDj{~_1Nz!sS&!!?3G$pnOqe!EkbWB!;)Xf_#e{9z$} zTRM6h%97P^W?&orxfHG^-!)?y7LA)K9Tz{nhmsFZpj1cpHheoXaGCyW4TpHvl=;X= zO!MhGTUmngmyZ!07Ymgpy89(pm;n}iQ~p(aby7MqC(rZgdt6t86J?j+a=V1%D6IyO zu^Px^(&l^3478!^ttLSslVj)fC73j1G^)SXq43Qkzv7F>r3hoaZj2XS>TtO90_;ww z&sdd44fWtyajbzE=rvGhCnRHkdWLj-_tSG+es#a+xKYX2J98!EWLU)eA77v=E`Y^u z>(wxehnOK+$mDYPH83k72?x?w`SjhYtwQO$D(QIIu<VM(j_0!OsI=};Y zgrYrQ5Gv&nf=F^)g4E}ByHWO`8cQckhg#W{I(~Pw3F1u#u0lw}n?AQ;6lJvB1(_JD zjrV&OL#GkhH}cWY(iDt1!&RiV~# zh%?-%)a7pq`gPo2rADG=C~E6J;ah9aYc7IirxY^qHspfD(r!X$3+-Sx?-f2MAaOzK zpGq=^)dpizD_jmI?)|k4d4{v1bS{b4iXCAo%UN)T;zGX@$al;tGuzbx-I6G4BN*i2@ae(B+M^#}|$?Q6ZCJfH!OiI6_coOTC{KU;(r zf1~|8Q75iBw*fCBL4TaOT`sG!xwX`8w&hjkoDP^M`ZVBWg!}WHVxqiwqmJvX^apx_ VdDA8u`6~bb002ovPDHLkV1koM?D7Br literal 0 HcmV?d00001 diff --git a/www/img/zajic.webp b/www/img/zajic.webp new file mode 100644 index 0000000000000000000000000000000000000000..0a9bbe53bf4f60375eed8ee49ed58e0e454dc2ef GIT binary patch literal 58446 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 literal 0 HcmV?d00001 diff --git a/www/img/zaznamy32x32.png b/www/img/zaznamy32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..8259fdf49c3053056e4050324fe0ff1ff5291131 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyoCO|{#S9F5M?jcysy3fAP_Qn* zC&bmgz$b9>!@#<&P8B<%T6Q|;FI9C))ATCz>AD;=<&jZt|<%ENkKq)C-h-^5n_vJ&(;( zW(3x5ef;>bZT?F0&qOJqud{DK+k-xt@{ch0P@FBTH2 ztGB8L0gi$KtNObA373`1fa+R2T^vI!PT#$JQmDy*ry-Fgl11E1P-OMgzklN=_^Ds+ zo4^zPVE;2~RpG-oJj_3{&$Q&y^ZDx1xc1=d720y&Eq`R65P7lc{F+tCE16Eja7<(9 zxTPN@&9q}*XA*-PD_?Lxap3xcnOt6xn_0FjaM)R_V1BaFm+6(59jgvQ`f=Cdrm1`G Za-4c>Ehkz!9~hhr44$rjF6*2UngDSYm^lCd literal 0 HcmV?d00001 diff --git a/www/img/zena32x32.png b/www/img/zena32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..016a4a0dca499c08d76b2aa20dad722578aca8b3 GIT binary patch literal 1350 zcmV-M1-bf(P) z2}~4M7=ZtoVOh7ZKsXyIAT6R4a9Kc(Wd*5_A|b(}AYj!%#iod9piL^Z6l{@D8>&$u z)S?BoMOthB&Vy1?#C-)=f&IhJKv_>-6S{{Q{+{%_v=|9cq> zRv}JKPPXdm>Yt(^A2l{=W2m)I6!rVa$VgUud;9E4*TR$y&g1cdF$~KU#|I@TP((b18M-n?R&;Is@1g~IK1b#()43gGJM`T%tv3+)7f!yCp1qTaq?H5qeW zd3m|tngMV)94?E+s#|J~?_vXqabfU7<{xnV=AX2g5{X2-nwpx5H34vTc1}XwXG_gp z{5BFCxt7v#@}(Texm`+6WmHyHhOP+!%KRGCIncU}jwXzbPJ*-JRydy&0Vpx0cA;Zm{{h}Ub#nR{(K*ojHjok`Atnt4^;xNw6t{4($cCqam)|i5A>AUh6JP31}1~j(bB*d z`d8F+P#>SXEL|I&4X0{rYZFxhu(7cTLFM;TRD>S{?c*!-f6_AqA>rp~^;cAmfhqxT zx!icv#U1~^8x994254;`fUpynX|=k(zTQbC06ROoGSu-81-L+D_%4P1#ifrRCgC?) z?P_Rfuv8kr*w`3H-<^ZDJ_e})65CF<&G1dEze0f2AIl&!yOLI)G&VL`CQ^-w^`CpS1sI_ki&8&q%q3pzRLQ5D!Ly#uzkw&AEtK+RCr zzGwH_5EHpW?vuCj+Td(TnXKt0M z1r(tV{zuYb_}Qqe`{|aJmUyKBB!cRng+9d*G`xfwLEE?6Z-%twFc1lcffT<)ryv1@ zx&f%ObRqQk1*mK6o?8Q5&AiUe&hk|On3$O8vDxf9Xy`V#GkO4rLw3U6_q>;U=0;iu zoXhS4F)3B++uGXfmy4mW3=Itpan9>ogS83GGr_vvW*(bZ!0^oirVF}baAKaXNYDjS zxz+Hv^Z=Y0yf!YFdGSv5qxxEv0PgV4v0e4HC7{bD0{*WCd`liMe4YYhi|3plIXwwe zMLB>KosWiZlZ($UgJxjm!B4JLTT{sI2H$I4myJ05Z2&lGwOD{&j z)%@Xy;i0whw`Kw6{gk zp5i3|`n>W|kR@WBg44Uuo-c{?E9e}63F?*jIXV7?_dgLyw0+44-*Y~< zF=K5!%ETD%YCxFbfW4+dVBsu?yQis{(x<{_>ER7ux601{2bWU2Frwe_Q~&?~07*qo IM6N<$f+b^x2LJ#7 literal 0 HcmV?d00001 diff --git a/www/index.php b/www/index.php new file mode 100644 index 0000000..d6e6884 --- /dev/null +++ b/www/index.php @@ -0,0 +1,10 @@ +bootWebApplication(); +$application = $container->getByType(Nette\Application\Application::class); +$application->run(); diff --git a/www/js/bootstrap.bundle.min.js b/www/js/bootstrap.bundle.min.js new file mode 100644 index 0000000..c42ea9b --- /dev/null +++ b/www/js/bootstrap.bundle.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.3.0-alpha2 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),i=e=>{e.dispatchEvent(new Event(t))},n=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),s=t=>n(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(e(t)):null,o=t=>{if(!n(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},r=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),a=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a(t.parentNode):null},l=()=>{},c=t=>{t.offsetHeight},h=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,d=[],u=()=>"rtl"===document.documentElement.dir,f=t=>{var e;e=()=>{const e=h();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(d.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of d)t()})),d.push(e)):e()},p=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,m=(e,n,s=!0)=>{if(!s)return void p(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(n)+5;let r=!1;const a=({target:i})=>{i===n&&(r=!0,n.removeEventListener(t,a),p(e))};n.addEventListener(t,a),setTimeout((()=>{r||i(n)}),o)},g=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},_=/[^.]*(?=\..*)\.|.*/,b=/\..*/,v=/::\d+$/,y={};let w=1;const A={mouseenter:"mouseover",mouseleave:"mouseout"},E=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function T(t,e){return e&&`${e}::${w++}`||t.uidEvent||w++}function C(t){const e=T(t);return t.uidEvent=e,y[e]=y[e]||{},y[e]}function O(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function x(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=D(t);return E.has(o)||(o=t),[n,s,o]}function k(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=x(e,i,n);if(e in A){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=C(t),c=l[a]||(l[a]={}),h=O(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=T(r,e.replace(_,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return N(s,{delegateTarget:r}),n.oneOff&&I.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return N(n,{delegateTarget:t}),i.oneOff&&I.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function L(t,e,i,n,s){const o=O(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function S(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&L(t,e,i,r.callable,r.delegationSelector)}function D(t){return t=t.replace(b,""),A[t]||t}const I={on(t,e,i,n){k(t,e,i,n,!1)},one(t,e,i,n){k(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=x(e,i,n),a=r!==e,l=C(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))S(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(v,"");a&&!e.includes(s)||L(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;L(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=h();let s=null,o=!0,r=!0,a=!1;e!==D(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=N(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function N(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}const P=new Map,j={set(t,e,i){P.has(t)||P.set(t,new Map);const n=P.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>P.has(t)&&P.get(t).get(e)||null,remove(t,e){if(!P.has(t))return;const i=P.get(t);i.delete(e),0===i.size&&P.delete(t)}};function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const H={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${F(e)}`))};class ${static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=n(e)?H.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...n(e)?H.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[s,o]of Object.entries(e)){const e=t[s],r=n(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${s}" provided type "${r}" but expected type "${o}".`)}var i}}class W extends ${constructor(t,e){super(),(t=s(t))&&(this._element=t,this._config=this._getConfig(e),j.set(this._element,this.constructor.DATA_KEY,this))}dispose(){j.remove(this._element,this.constructor.DATA_KEY),I.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){m(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return j.get(s(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.0-alpha2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let i=t.getAttribute("data-bs-target");if(!i||"#"===i){let e=t.getAttribute("href");if(!e||!e.includes("#")&&!e.startsWith("."))return null;e.includes("#")&&!e.startsWith("#")&&(e=`#${e.split("#")[1]}`),i=e&&"#"!==e?e.trim():null}return e(i)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!r(t)&&o(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;I.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),r(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))};class q extends W{static get NAME(){return"alert"}close(){if(I.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),I.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(q,"close"),f(q);const V='[data-bs-toggle="button"]';class K extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=K.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}I.on(document,"click.bs.button.data-api",V,(t=>{t.preventDefault();const e=t.target.closest(V);K.getOrCreateInstance(e).toggle()})),f(K);const Q={endCallback:null,leftCallback:null,rightCallback:null},X={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Y extends ${constructor(t,e){super(),this._element=t,t&&Y.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Q}static get DefaultType(){return X}static get NAME(){return"swipe"}dispose(){I.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),p(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&p(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(I.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),I.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(I.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),I.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),I.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const U="next",G="prev",J="left",Z="right",tt="slid.bs.carousel",et="carousel",it="active",nt={ArrowLeft:Z,ArrowRight:J},st={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class rt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===et&&this.cycle()}static get Default(){return st}static get DefaultType(){return ot}static get NAME(){return"carousel"}next(){this._slide(U)}nextWhenVisible(){!document.hidden&&o(this._element)&&this.next()}prev(){this._slide(G)}pause(){this._isSliding&&i(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?I.one(this._element,tt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void I.one(this._element,tt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?U:G;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&I.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(I.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),I.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&Y.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))I.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(J)),rightCallback:()=>this._slide(this._directionToOrder(Z)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Y(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=nt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(it),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===U,s=e||g(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>I.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",h=n?"carousel-item-next":"carousel-item-prev";s.classList.add(h),c(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,h),s.classList.add(it),i.classList.remove(it,h,l),this._isSliding=!1,r(tt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(".active.carousel-item",this._element)}_getItems(){return z.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return u()?t===J?G:U:t===J?U:G}_orderToDirection(t){return u()?t===G?J:Z:t===G?Z:J}static jQueryInterface(t){return this.each((function(){const e=rt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}I.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(et))return;t.preventDefault();const i=rt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===H.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),I.on(window,"load.bs.carousel.data-api",(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)rt.getOrCreateInstance(e)})),f(rt);const at="show",lt="collapse",ct="collapsing",ht='[data-bs-toggle="collapse"]',dt={parent:null,toggle:!0},ut={parent:"(null|element)",toggle:"boolean"};class ft extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(ht);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return dt}static get DefaultType(){return ut}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>ft.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(I.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(lt),this._element.classList.add(ct),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt,at),this._element.style[e]="",I.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(I.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,c(this._element),this._element.classList.add(ct),this._element.classList.remove(lt,at);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ct),this._element.classList.add(lt),I.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(at)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=s(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(ht);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(":scope .collapse .collapse",this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=ft.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}I.on(document,"click.bs.collapse.data-api",ht,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))ft.getOrCreateInstance(t,{toggle:!1}).toggle()})),f(ft);var pt="top",mt="bottom",gt="right",_t="left",bt="auto",vt=[pt,mt,gt,_t],yt="start",wt="end",At="clippingParents",Et="viewport",Tt="popper",Ct="reference",Ot=vt.reduce((function(t,e){return t.concat([e+"-"+yt,e+"-"+wt])}),[]),xt=[].concat(vt,[bt]).reduce((function(t,e){return t.concat([e,e+"-"+yt,e+"-"+wt])}),[]),kt="beforeRead",Lt="read",St="afterRead",Dt="beforeMain",It="main",Nt="afterMain",Pt="beforeWrite",jt="write",Mt="afterWrite",Ft=[kt,Lt,St,Dt,It,Nt,Pt,jt,Mt];function Ht(t){return t?(t.nodeName||"").toLowerCase():null}function $t(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function Wt(t){return t instanceof $t(t).Element||t instanceof Element}function Bt(t){return t instanceof $t(t).HTMLElement||t instanceof HTMLElement}function zt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof $t(t).ShadowRoot||t instanceof ShadowRoot)}const Rt={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];Bt(s)&&Ht(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});Bt(n)&&Ht(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function qt(t){return t.split("-")[0]}var Vt=Math.max,Kt=Math.min,Qt=Math.round;function Xt(){var t=navigator.userAgentData;return null!=t&&t.brands?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Yt(){return!/^((?!chrome|android).)*safari/i.test(Xt())}function Ut(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&Bt(t)&&(s=t.offsetWidth>0&&Qt(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Qt(n.height)/t.offsetHeight||1);var r=(Wt(t)?$t(t):window).visualViewport,a=!Yt()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Gt(t){var e=Ut(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Jt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&zt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Zt(t){return $t(t).getComputedStyle(t)}function te(t){return["table","td","th"].indexOf(Ht(t))>=0}function ee(t){return((Wt(t)?t.ownerDocument:t.document)||window.document).documentElement}function ie(t){return"html"===Ht(t)?t:t.assignedSlot||t.parentNode||(zt(t)?t.host:null)||ee(t)}function ne(t){return Bt(t)&&"fixed"!==Zt(t).position?t.offsetParent:null}function se(t){for(var e=$t(t),i=ne(t);i&&te(i)&&"static"===Zt(i).position;)i=ne(i);return i&&("html"===Ht(i)||"body"===Ht(i)&&"static"===Zt(i).position)?e:i||function(t){var e=/firefox/i.test(Xt());if(/Trident/i.test(Xt())&&Bt(t)&&"fixed"===Zt(t).position)return null;var i=ie(t);for(zt(i)&&(i=i.host);Bt(i)&&["html","body"].indexOf(Ht(i))<0;){var n=Zt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function oe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function re(t,e,i){return Vt(t,Kt(e,i))}function ae(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function le(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const ce={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=qt(i.placement),l=oe(a),c=[_t,gt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return ae("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:le(t,vt))}(s.padding,i),d=Gt(o),u="y"===l?pt:_t,f="y"===l?mt:gt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=se(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=re(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Jt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(t){return t.split("-")[1]}var de={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ue(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=_t,y=pt,w=window;if(c){var A=se(i),E="clientHeight",T="clientWidth";A===$t(i)&&"static"!==Zt(A=ee(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===pt||(s===_t||s===gt)&&o===wt)&&(y=mt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==_t&&(s!==pt&&s!==mt||o!==wt)||(v=gt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&de),x=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:Qt(e*n)/n||0,y:Qt(i*n)/n||0}}({x:f,y:m}):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const fe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:qt(e.placement),variation:he(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ue(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ue(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var pe={passive:!0};const me={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=$t(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,pe)})),a&&l.addEventListener("resize",i.update,pe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,pe)})),a&&l.removeEventListener("resize",i.update,pe)}},data:{}};var ge={left:"right",right:"left",bottom:"top",top:"bottom"};function _e(t){return t.replace(/left|right|bottom|top/g,(function(t){return ge[t]}))}var be={start:"end",end:"start"};function ve(t){return t.replace(/start|end/g,(function(t){return be[t]}))}function ye(t){var e=$t(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function we(t){return Ut(ee(t)).left+ye(t).scrollLeft}function Ae(t){var e=Zt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Ht(t))>=0?t.ownerDocument.body:Bt(t)&&Ae(t)?t:Ee(ie(t))}function Te(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=$t(n),r=s?[o].concat(o.visualViewport||[],Ae(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Te(ie(r)))}function Ce(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e,i){return e===Et?Ce(function(t,e){var i=$t(t),n=ee(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Yt();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+we(t),y:l}}(t,i)):Wt(e)?function(t,e){var i=Ut(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ce(function(t){var e,i=ee(t),n=ye(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=Vt(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=Vt(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+we(t),l=-n.scrollTop;return"rtl"===Zt(s||i).direction&&(a+=Vt(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(ee(t)))}function xe(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?qt(s):null,r=s?he(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case pt:e={x:a,y:i.y-n.height};break;case mt:e={x:a,y:i.y+i.height};break;case gt:e={x:i.x+i.width,y:l};break;case _t:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?oe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case yt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case wt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?At:a,c=i.rootBoundary,h=void 0===c?Et:c,d=i.elementContext,u=void 0===d?Tt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=ae("number"!=typeof g?g:le(g,vt)),b=u===Tt?Ct:Tt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Te(ie(t)),i=["absolute","fixed"].indexOf(Zt(t).position)>=0&&Bt(t)?se(t):t;return Wt(i)?e.filter((function(t){return Wt(t)&&Jt(t,i)&&"body"!==Ht(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=Oe(t,i,n);return e.top=Vt(s.top,e.top),e.right=Kt(s.right,e.right),e.bottom=Kt(s.bottom,e.bottom),e.left=Vt(s.left,e.left),e}),Oe(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(Wt(y)?y:y.contextElement||ee(t.elements.popper),l,h,r),A=Ut(t.elements.reference),E=xe({reference:A,element:v,strategy:"absolute",placement:s}),T=Ce(Object.assign({},v,E)),C=u===Tt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Tt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[gt,mt].indexOf(t)>=0?1:-1,i=[pt,mt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?xt:l,h=he(n),d=h?a?Ot:Ot.filter((function(t){return he(t)===h})):vt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[qt(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const Se={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=qt(g),b=l||(_!==g&&p?function(t){if(qt(t)===bt)return[];var e=_e(t);return[ve(t),e,ve(e)]}(g):[_e(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(qt(i)===bt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=ke(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),I=L?k?gt:_t:k?mt:pt;y[S]>w[S]&&(I=_e(I));var N=_e(I),P=[];if(o&&P.push(D[x]<=0),a&&P.push(D[I]<=0,D[N]<=0),P.every((function(t){return t}))){T=O,E=!1;break}A.set(O,P)}if(E)for(var j=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Ie(t){return[pt,gt,mt,_t].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Ie(l),d=Ie(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Pe={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=xt.reduce((function(t,i){return t[i]=function(t,e,i){var n=qt(t),s=[_t,pt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[_t,gt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},je={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=xe({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Me={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=qt(e.placement),b=he(e.placement),v=!b,y=oe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?pt:_t,D="y"===y?mt:gt,I="y"===y?"height":"width",N=A[y],P=N+g[S],j=N-g[D],M=f?-T[I]/2:0,F=b===yt?E[I]:T[I],H=b===yt?-T[I]:-E[I],$=e.elements.arrow,W=f&&$?Gt($):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=re(0,E[I],W[I]),V=v?E[I]/2-M-q-z-O.mainAxis:F-q-z-O.mainAxis,K=v?-E[I]/2+M+q+R+O.mainAxis:H+q+R+O.mainAxis,Q=e.elements.arrow&&se(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=N+K-Y,G=re(f?Kt(P,N+V-Y-X):P,N,f?Vt(j,U):j);A[y]=G,k[y]=G-N}if(a){var J,Z="x"===y?pt:_t,tt="x"===y?mt:gt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[pt,_t].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=re(t,e,i);return n>i?i:n}(at,et,lt):re(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function Fe(t,e,i){void 0===i&&(i=!1);var n,s,o=Bt(e),r=Bt(e)&&function(t){var e=t.getBoundingClientRect(),i=Qt(e.width)/t.offsetWidth||1,n=Qt(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=ee(e),l=Ut(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==Ht(e)||Ae(a))&&(c=(n=e)!==$t(n)&&Bt(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:ye(n)),Bt(e)?((h=Ut(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=we(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var $e={placement:"bottom",modifiers:[],strategy:"absolute"};function We(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(H.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...p(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>o(t)));i.length&&g(i,e,t===Xe,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=ci.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ze);for(const i of e){const e=ci.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Qe,Xe].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Je)?this:z.prev(this,Je)[0]||z.next(this,Je)[0]||z.findOne(Je,t.delegateTarget.parentNode),o=ci.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}I.on(document,Ue,Je,ci.dataApiKeydownHandler),I.on(document,Ue,ti,ci.dataApiKeydownHandler),I.on(document,Ye,ci.clearMenus),I.on(document,"keyup.bs.dropdown.data-api",ci.clearMenus),I.on(document,Ye,Je,(function(t){t.preventDefault(),ci.getOrCreateInstance(this).toggle()})),f(ci);const hi=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",di=".sticky-top",ui="padding-right",fi="margin-right";class pi{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,ui,(e=>e+t)),this._setElementAttributes(hi,ui,(e=>e+t)),this._setElementAttributes(di,fi,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,ui),this._resetElementAttributes(hi,ui),this._resetElementAttributes(di,fi)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&H.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=H.getDataAttribute(t,e);null!==i?(H.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(n(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const mi="show",gi="mousedown.bs.backdrop",_i={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},bi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class vi extends ${constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return _i}static get DefaultType(){return bi}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void p(t);this._append();const e=this._getElement();this._config.isAnimated&&c(e),e.classList.add(mi),this._emulateAnimation((()=>{p(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(mi),this._emulateAnimation((()=>{this.dispose(),p(t)}))):p(t)}dispose(){this._isAppended&&(I.off(this._element,gi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=s(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),I.on(t,gi,(()=>{p(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){m(t,this._getElement(),this._config.isAnimated)}}const yi=".bs.focustrap",wi="backward",Ai={autofocus:!0,trapElement:null},Ei={autofocus:"boolean",trapElement:"element"};class Ti extends ${constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Ai}static get DefaultType(){return Ei}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),I.off(document,yi),I.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),I.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,I.off(document,yi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===wi?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?wi:"forward")}}const Ci="hidden.bs.modal",Oi="show.bs.modal",xi="modal-open",ki="show",Li="modal-static",Si={backdrop:!0,focus:!0,keyboard:!0},Di={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class Ii extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new pi,this._addEventListeners()}static get Default(){return Si}static get DefaultType(){return Di}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||I.trigger(this._element,Oi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(xi),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(I.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(ki),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])I.off(t,".bs.modal");this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new vi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ti({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),c(this._element),this._element.classList.add(ki),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,I.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){I.on(this._element,"keydown.dismiss.bs.modal",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),I.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),I.on(this._element,"mousedown.dismiss.bs.modal",(t=>{I.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(xi),this._resetAdjustments(),this._scrollBar.reset(),I.trigger(this._element,Ci)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(I.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Li)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Li),this._queueCallback((()=>{this._element.classList.remove(Li),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=u()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=u()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Ii.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}I.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),I.one(e,Oi,(t=>{t.defaultPrevented||I.one(e,Ci,(()=>{o(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&Ii.getInstance(i).hide(),Ii.getOrCreateInstance(e).toggle(this)})),R(Ii),f(Ii);const Ni="show",Pi="showing",ji="hiding",Mi=".offcanvas.show",Fi="hidePrevented.bs.offcanvas",Hi="hidden.bs.offcanvas",$i={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Bi extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return $i}static get DefaultType(){return Wi}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||I.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new pi).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Pi),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Ni),this._element.classList.remove(Pi),I.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(I.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ji),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Ni,ji),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new pi).reset(),I.trigger(this._element,Hi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new vi({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():I.trigger(this._element,Fi)}:null})}_initializeFocusTrap(){return new Ti({trapElement:this._element})}_addEventListeners(){I.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():I.trigger(this._element,Fi))}))}static jQueryInterface(t){return this.each((function(){const e=Bi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}I.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),r(this))return;I.one(e,Hi,(()=>{o(this)&&this.focus()}));const i=z.findOne(Mi);i&&i!==e&&Bi.getInstance(i).hide(),Bi.getOrCreateInstance(e).toggle(this)})),I.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of z.find(Mi))Bi.getOrCreateInstance(t).show()})),I.on(window,"resize.bs.offcanvas",(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Bi.getOrCreateInstance(t).hide()})),R(Bi),f(Bi);const zi=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Ri=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,qi=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Vi=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!zi.has(i)||Boolean(Ri.test(t.nodeValue)||qi.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Ki={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Qi={allowList:Ki,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Xi={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Yi={entry:"(string|element|function|null)",selector:"(string|element)"};class Ui extends ${constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Qi}static get DefaultType(){return Xi}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Yi)}_setContent(t,e,i){const o=z.findOne(i,t);o&&((e=this._resolvePossibleFunction(e))?n(e)?this._putElementInTemplate(s(e),o):this._config.html?o.innerHTML=this._maybeSanitize(e):o.textContent=e:o.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Vi(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return p(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Gi=new Set(["sanitize","allowList","sanitizeFn"]),Ji="fade",Zi="show",tn=".modal",en="hide.bs.modal",nn="hover",sn="focus",on={AUTO:"auto",TOP:"top",RIGHT:u()?"left":"right",BOTTOM:"bottom",LEFT:u()?"right":"left"},rn={allowList:Ki,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},an={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class ln extends W{constructor(t,e){if(void 0===Ve)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return rn}static get DefaultType(){return an}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),I.off(this._element.closest(tn),en,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=I.trigger(this._element,this.constructor.eventName("show")),e=(a(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),I.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))I.on(t,"mouseover",l);this._queueCallback((()=>{I.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!I.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Zi),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))I.off(t,"mouseover",l);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),I.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ji,Zi),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Ji),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ui({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ji)}_isShown(){return this.tip&&this.tip.classList.contains(Zi)}_createPopper(t){const e=p(this._config.placement,[this,t,this._element]),i=on[e.toUpperCase()];return qe(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return p(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...p(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)I.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===nn?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===nn?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");I.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?sn:nn]=!0,e._enter()})),I.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?sn:nn]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},I.on(this._element.closest(tn),en,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=H.getDataAttributes(this._element);for(const t of Object.keys(e))Gi.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:s(t.container),"number"==typeof 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()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=ln.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}f(ln);const cn={...ln.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},hn={...ln.DefaultType,content:"(null|string|element|function)"};class dn extends ln{static get Default(){return cn}static get DefaultType(){return hn}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=dn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}f(dn);const un="click.bs.scrollspy",fn="active",pn="[href]",mn={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},gn={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class _n extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return mn}static get DefaultType(){return gn}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=s(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(I.off(this._config.target,un),I.on(this._config.target,un,pn,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(pn,this._config.target);for(const e of t){if(!e.hash||r(e))continue;const t=z.findOne(e.hash,this._element);o(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(fn),this._activateParents(t),I.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(fn);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(fn)}_clearActiveClass(t){t.classList.remove(fn);const e=z.find("[href].active",t);for(const t of e)t.classList.remove(fn)}static jQueryInterface(t){return this.each((function(){const e=_n.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))_n.getOrCreateInstance(t)})),f(_n);const bn="ArrowLeft",vn="ArrowRight",yn="ArrowUp",wn="ArrowDown",An="active",En="fade",Tn="show",Cn='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',On=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Cn}`;class xn extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),I.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?I.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;I.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(An),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),I.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Tn)}),t,t.classList.contains(En)))}_deactivate(t,e){t&&(t.classList.remove(An),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),I.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Tn)}),t,t.classList.contains(En)))}_keydown(t){if(![bn,vn,yn,wn].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[vn,wn].includes(t.key),i=g(this._getChildren().filter((t=>!r(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),xn.getOrCreateInstance(i).show())}_getChildren(){return z.find(On,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",An),n(".dropdown-menu",Tn),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(An)}_getInnerElement(t){return t.matches(On)?t:z.findOne(On,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}I.on(document,"click.bs.tab",Cn,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),r(this)||xn.getOrCreateInstance(this).show()})),I.on(window,"load.bs.tab",(()=>{for(const t of z.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))xn.getOrCreateInstance(t)})),f(xn);const kn="hide",Ln="show",Sn="showing",Dn={animation:"boolean",autohide:"boolean",delay:"number"},In={animation:!0,autohide:!0,delay:5e3};class Nn extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return In}static get DefaultType(){return Dn}static get NAME(){return"toast"}show(){I.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(kn),c(this._element),this._element.classList.add(Ln,Sn),this._queueCallback((()=>{this._element.classList.remove(Sn),I.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(I.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(Sn),this._queueCallback((()=>{this._element.classList.add(kn),this._element.classList.remove(Sn,Ln),I.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(Ln),super.dispose()}isShown(){return this._element.classList.contains(Ln)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){I.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),I.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),I.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),I.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Nn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Nn),f(Nn),{Alert:q,Button:K,Carousel:rt,Collapse:ft,Dropdown:ci,Modal:Ii,Offcanvas:Bi,Popover:dn,ScrollSpy:_n,Tab:xn,Toast:Nn,Tooltip:ln}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/www/js/bootstrap.bundle.min.js.map b/www/js/bootstrap.bundle.min.js.map new file mode 100644 index 0000000..2839fef --- /dev/null +++ b/www/js/bootstrap.bundle.min.js.map @@ -0,0 +1 @@ +{"version":3,"names":["TRANSITION_END","parseSelector","selector","window","CSS","escape","replace","match","id","triggerTransitionEnd","element","dispatchEvent","Event","isElement","object","jquery","nodeType","getElement","length","document","querySelector","isVisible","getClientRects","elementIsVisible","getComputedStyle","getPropertyValue","closedDetails","closest","summary","parentNode","isDisabled","Node","ELEMENT_NODE","classList","contains","disabled","hasAttribute","getAttribute","findShadowRoot","documentElement","attachShadow","getRootNode","root","ShadowRoot","noop","reflow","offsetHeight","getjQuery","jQuery","body","DOMContentLoadedCallbacks","isRTL","dir","defineJQueryPlugin","plugin","callback","$","name","NAME","JQUERY_NO_CONFLICT","fn","jQueryInterface","Constructor","noConflict","readyState","addEventListener","push","execute","possibleCallback","args","defaultValue","executeAfterTransition","transitionElement","waitForTransition","emulatedDuration","transitionDuration","transitionDelay","floatTransitionDuration","Number","parseFloat","floatTransitionDelay","split","getTransitionDurationFromElement","called","handler","target","removeEventListener","setTimeout","getNextActiveElement","list","activeElement","shouldGetNext","isCycleAllowed","listLength","index","indexOf","Math","max","min","namespaceRegex","stripNameRegex","stripUidRegex","eventRegistry","uidEvent","customEvents","mouseenter","mouseleave","nativeEvents","Set","makeEventUid","uid","getElementEvents","findHandler","events","callable","delegationSelector","Object","values","find","event","normalizeParameters","originalTypeEvent","delegationFunction","isDelegated","typeEvent","getTypeEvent","has","addHandler","oneOff","wrapFunction","relatedTarget","delegateTarget","call","this","handlers","previousFunction","domElements","querySelectorAll","domElement","hydrateObj","EventHandler","off","type","apply","bootstrapDelegationHandler","bootstrapHandler","removeHandler","Boolean","removeNamespacedHandlers","namespace","storeElementEvent","handlerKey","entries","includes","on","one","inNamespace","isNamespace","startsWith","elementEvent","keys","slice","keyHandlers","trigger","jQueryEvent","bubbles","nativeDispatch","defaultPrevented","isPropagationStopped","isImmediatePropagationStopped","isDefaultPrevented","evt","cancelable","preventDefault","obj","meta","key","value","_unused","defineProperty","configurable","get","elementMap","Map","Data","set","instance","instanceMap","size","console","error","Array","from","remove","delete","normalizeData","toString","JSON","parse","decodeURIComponent","normalizeDataKey","chr","toLowerCase","Manipulator","setDataAttribute","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","bsKeys","dataset","filter","pureKey","charAt","getDataAttribute","Config","Default","DefaultType","Error","_getConfig","config","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","jsonConfig","constructor","configTypes","property","expectedTypes","valueType","prototype","RegExp","test","TypeError","toUpperCase","BaseComponent","super","_element","_config","DATA_KEY","dispose","EVENT_KEY","propertyName","getOwnPropertyNames","_queueCallback","isAnimated","static","getInstance","VERSION","getSelector","hrefAttribute","trim","SelectorEngine","concat","Element","findOne","children","child","matches","parents","ancestor","prev","previous","previousElementSibling","next","nextElementSibling","focusableChildren","focusables","map","join","el","getSelectorFromElement","getElementFromSelector","getMultipleElementsFromSelector","enableDismissTrigger","component","method","clickEvent","tagName","getOrCreateInstance","Alert","close","_destroyElement","each","data","undefined","SELECTOR_DATA_TOGGLE","Button","toggle","button","endCallback","leftCallback","rightCallback","Swipe","isSupported","_deltaX","_supportPointerEvents","PointerEvent","_initEvents","_start","_eventIsPointerPenTouch","clientX","touches","_end","_handleSwipe","_move","absDeltaX","abs","direction","add","pointerType","navigator","maxTouchPoints","ORDER_NEXT","ORDER_PREV","DIRECTION_LEFT","DIRECTION_RIGHT","EVENT_SLID","CLASS_NAME_CAROUSEL","CLASS_NAME_ACTIVE","KEY_TO_DIRECTION","ArrowLeft","ArrowRight","interval","keyboard","pause","ride","touch","wrap","Carousel","_interval","_activeElement","_isSliding","touchTimeout","_swipeHelper","_indicatorsElement","_addEventListeners","cycle","_slide","nextWhenVisible","hidden","_clearInterval","_updateInterval","setInterval","_maybeEnableCycle","to","items","_getItems","activeIndex","_getItemIndex","_getActive","order","defaultInterval","_keydown","_addTouchEventListeners","img","swipeConfig","_directionToOrder","endCallBack","clearTimeout","_setActiveIndicatorElement","activeIndicator","newActiveIndicator","elementInterval","parseInt","isNext","nextElement","nextElementIndex","triggerEvent","eventName","_orderToDirection","isCycling","directionalClassName","orderClassName","completeCallBack","_isAnimated","SELECTOR_ACTIVE","clearInterval","carousel","slideIndex","carousels","CLASS_NAME_SHOW","CLASS_NAME_COLLAPSE","CLASS_NAME_COLLAPSING","parent","Collapse","_isTransitioning","_triggerArray","toggleList","elem","filterElement","foundElement","_initializeChildren","_addAriaAndCollapsedClass","_isShown","hide","show","activeChildren","_getFirstLevelChildren","activeInstance","dimension","_getDimension","style","scrollSize","complete","getBoundingClientRect","selected","triggerArray","isOpen","top","bottom","right","left","auto","basePlacements","start","end","clippingParents","viewport","popper","reference","variationPlacements","reduce","acc","placement","placements","beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite","modifierPhases","getNodeName","nodeName","getWindow","node","ownerDocument","defaultView","isHTMLElement","HTMLElement","isShadowRoot","applyStyles$1","enabled","phase","_ref","state","elements","forEach","styles","assign","effect","_ref2","initialStyles","position","options","strategy","margin","arrow","hasOwnProperty","attribute","requires","getBasePlacement","round","getUAString","uaData","userAgentData","brands","item","brand","version","userAgent","isLayoutViewport","includeScale","isFixedStrategy","clientRect","scaleX","scaleY","offsetWidth","width","height","visualViewport","addVisualOffsets","x","offsetLeft","y","offsetTop","getLayoutRect","rootNode","isSameNode","host","isTableElement","getDocumentElement","getParentNode","assignedSlot","getTrueOffsetParent","offsetParent","getOffsetParent","isFirefox","currentNode","css","transform","perspective","contain","willChange","getContainingBlock","getMainAxisFromPlacement","within","mathMax","mathMin","mergePaddingObject","paddingObject","expandToHashMap","hashMap","arrow$1","_state$modifiersData$","arrowElement","popperOffsets","modifiersData","basePlacement","axis","len","padding","rects","toPaddingObject","arrowRect","minProp","maxProp","endDiff","startDiff","arrowOffsetParent","clientSize","clientHeight","clientWidth","centerToReference","center","offset","axisProp","centerOffset","_options$element","requiresIfExists","getVariation","unsetSides","mapToStyles","_Object$assign2","popperRect","variation","offsets","gpuAcceleration","adaptive","roundOffsets","isFixed","_offsets$x","_offsets$y","_ref3","hasX","hasY","sideX","sideY","win","heightProp","widthProp","_Object$assign","commonStyles","_ref4","dpr","devicePixelRatio","roundOffsetsByDPR","computeStyles$1","_ref5","_options$gpuAccelerat","_options$adaptive","_options$roundOffsets","passive","eventListeners","_options$scroll","scroll","_options$resize","resize","scrollParents","scrollParent","update","hash","getOppositePlacement","matched","getOppositeVariationPlacement","getWindowScroll","scrollLeft","pageXOffset","scrollTop","pageYOffset","getWindowScrollBarX","isScrollParent","_getComputedStyle","overflow","overflowX","overflowY","getScrollParent","listScrollParents","_element$ownerDocumen","isBody","updatedList","rectToClientRect","rect","getClientRectFromMixedType","clippingParent","html","layoutViewport","getViewportRect","clientTop","clientLeft","getInnerBoundingClientRect","winScroll","scrollWidth","scrollHeight","getDocumentRect","computeOffsets","commonX","commonY","mainAxis","detectOverflow","_options","_options$placement","_options$strategy","_options$boundary","boundary","_options$rootBoundary","rootBoundary","_options$elementConte","elementContext","_options$altBoundary","altBoundary","_options$padding","altContext","clippingClientRect","mainClippingParents","clipperElement","getClippingParents","firstClippingParent","clippingRect","accRect","getClippingRect","contextElement","referenceClientRect","popperClientRect","elementClientRect","overflowOffsets","offsetData","multiply","computeAutoPlacement","flipVariations","_options$allowedAutoP","allowedAutoPlacements","allPlacements","allowedPlacements","overflows","sort","a","b","flip$1","_skip","_options$mainAxis","checkMainAxis","_options$altAxis","altAxis","checkAltAxis","specifiedFallbackPlacements","fallbackPlacements","_options$flipVariatio","preferredPlacement","oppositePlacement","getExpandedFallbackPlacements","referenceRect","checksMap","makeFallbackChecks","firstFittingPlacement","i","_basePlacement","isStartVariation","isVertical","mainVariationSide","altVariationSide","checks","every","check","_loop","_i","fittingPlacement","reset","getSideOffsets","preventedOffsets","isAnySideFullyClipped","some","side","hide$1","preventOverflow","referenceOverflow","popperAltOverflow","referenceClippingOffsets","popperEscapeOffsets","isReferenceHidden","hasPopperEscaped","offset$1","_options$offset","invertDistance","skidding","distance","distanceAndSkiddingToXY","_data$state$placement","popperOffsets$1","preventOverflow$1","_options$tether","tether","_options$tetherOffset","tetherOffset","isBasePlacement","tetherOffsetValue","normalizedTetherOffsetValue","offsetModifierState","_offsetModifierState$","mainSide","altSide","additive","minLen","maxLen","arrowPaddingObject","arrowPaddingMin","arrowPaddingMax","arrowLen","minOffset","maxOffset","clientOffset","offsetModifierValue","tetherMax","preventedOffset","_offsetModifierState$2","_mainSide","_altSide","_offset","_len","_min","_max","isOriginSide","_offsetModifierValue","_tetherMin","_tetherMax","_preventedOffset","v","withinMaxClamp","getCompositeRect","elementOrVirtualElement","isOffsetParentAnElement","offsetParentIsScaled","isElementScaled","modifiers","visited","result","modifier","dep","depModifier","DEFAULT_OPTIONS","areValidElements","arguments","_key","popperGenerator","generatorOptions","_generatorOptions","_generatorOptions$def","defaultModifiers","_generatorOptions$def2","defaultOptions","pending","orderedModifiers","effectCleanupFns","isDestroyed","setOptions","setOptionsAction","cleanupModifierEffects","merged","orderModifiers","current","existing","m","_ref3$options","cleanupFn","forceUpdate","_state$elements","_state$orderedModifie","_state$orderedModifie2","Promise","resolve","then","destroy","onFirstUpdate","createPopper","computeStyles","applyStyles","flip","ARROW_UP_KEY","ARROW_DOWN_KEY","EVENT_CLICK_DATA_API","EVENT_KEYDOWN_DATA_API","SELECTOR_DATA_TOGGLE_SHOWN","SELECTOR_MENU","PLACEMENT_TOP","PLACEMENT_TOPEND","PLACEMENT_BOTTOM","PLACEMENT_BOTTOMEND","PLACEMENT_RIGHT","PLACEMENT_LEFT","autoClose","display","popperConfig","Dropdown","_popper","_parent","_menu","_inNavbar","_detectNavbar","_createPopper","focus","_completeHide","Popper","referenceElement","_getPopperConfig","_getPlacement","parentDropdown","isEnd","_getOffset","popperData","defaultBsPopperConfig","_selectMenuItem","openToggles","context","composedPath","isMenuTarget","isInput","isEscapeEvent","isUpOrDownEvent","getToggleButton","stopPropagation","dataApiKeydownHandler","clearMenus","SELECTOR_FIXED_CONTENT","SELECTOR_STICKY_CONTENT","PROPERTY_PADDING","PROPERTY_MARGIN","ScrollBarHelper","getWidth","documentWidth","innerWidth","_disableOverFlow","_setElementAttributes","calculatedValue","_resetElementAttributes","isOverflowing","_saveInitialAttribute","styleProperty","scrollbarWidth","_applyManipulationCallback","setProperty","actualValue","removeProperty","callBack","sel","EVENT_MOUSEDOWN","className","clickCallback","rootElement","Backdrop","_isAppended","_append","_getElement","_emulateAnimation","backdrop","createElement","append","TAB_NAV_BACKWARD","autofocus","trapElement","FocusTrap","_isActive","_lastTabNavDirection","activate","_handleFocusin","_handleKeydown","deactivate","shiftKey","EVENT_HIDDEN","EVENT_SHOW","CLASS_NAME_OPEN","CLASS_NAME_STATIC","Modal","_dialog","_backdrop","_initializeBackDrop","_focustrap","_initializeFocusTrap","_scrollBar","_adjustDialog","_showElement","_hideModal","htmlElement","handleUpdate","modalBody","transitionComplete","_triggerBackdropTransition","event2","_resetAdjustments","isModalOverflowing","initialOverflowY","isBodyOverflowing","paddingLeft","paddingRight","showEvent","alreadyOpen","CLASS_NAME_SHOWING","CLASS_NAME_HIDING","OPEN_SELECTOR","EVENT_HIDE_PREVENTED","Offcanvas","blur","completeCallback","uriAttributes","SAFE_URL_PATTERN","DATA_URL_PATTERN","allowedAttribute","allowedAttributeList","attributeName","nodeValue","attributeRegex","regex","DefaultAllowlist","area","br","col","code","div","em","hr","h1","h2","h3","h4","h5","h6","li","ol","p","pre","s","small","span","sub","sup","strong","u","ul","allowList","content","extraClass","sanitize","sanitizeFn","template","DefaultContentType","entry","TemplateFactory","getContent","_resolvePossibleFunction","hasContent","changeContent","_checkContent","toHtml","templateWrapper","innerHTML","_maybeSanitize","text","_setContent","arg","templateElement","_putElementInTemplate","textContent","unsafeHtml","sanitizeFunction","createdDocument","DOMParser","parseFromString","elementName","attributeList","allowedAttributes","sanitizeHtml","DISALLOWED_ATTRIBUTES","CLASS_NAME_FADE","SELECTOR_MODAL","EVENT_MODAL_HIDE","TRIGGER_HOVER","TRIGGER_FOCUS","AttachmentMap","AUTO","TOP","RIGHT","BOTTOM","LEFT","animation","container","customClass","delay","title","Tooltip","_isEnabled","_timeout","_isHovered","_activeTrigger","_templateFactory","_newContent","tip","_setListeners","_fixTitle","enable","disable","toggleEnabled","click","_leave","_enter","_hideModalHandler","_disposePopper","_isWithContent","isInTheDom","_getTipElement","_isWithActiveTrigger","_getTitle","_createTipElement","_getContentForTemplate","_getTemplateFactory","tipId","prefix","floor","random","getElementById","getUID","setContent","_initializeOnDelegatedTarget","_getDelegateConfig","attachment","triggers","eventIn","eventOut","_setTimeout","timeout","dataAttributes","dataAttribute","Popover","_getContent","EVENT_CLICK","SELECTOR_TARGET_LINKS","rootMargin","smoothScroll","threshold","ScrollSpy","_targetLinks","_observableSections","_rootElement","_activeTarget","_observer","_previousScrollData","visibleEntryTop","parentScrollTop","refresh","_initializeTargetsAndObservables","_maybeEnableSmoothScroll","disconnect","_getNewObserver","section","observe","observableSection","scrollTo","behavior","IntersectionObserver","_observerCallback","targetElement","_process","userScrollsDown","isIntersecting","_clearActiveClass","entryIsLowerThanPrevious","targetLinks","anchor","_activateParents","listGroup","activeNodes","spy","ARROW_LEFT_KEY","ARROW_RIGHT_KEY","SELECTOR_INNER_ELEM","Tab","_setInitialAttributes","_getChildren","innerElem","_elemIsActive","active","_getActiveElem","hideEvent","_deactivate","_activate","relatedElem","_toggleDropDown","nextActiveElement","preventScroll","_setAttributeIfNotExists","_setInitialAttributesOnChild","_getInnerElement","isActive","outerElem","_getOuterElement","_setInitialAttributesOnTargetPanel","open","CLASS_NAME_HIDE","autohide","Toast","_hasMouseInteraction","_hasKeyboardInteraction","_clearTimeout","_maybeScheduleHide","isShown","_onInteraction","isInteracting"],"sources":["../../js/src/util/index.js","../../js/src/dom/event-handler.js","../../js/src/dom/data.js","../../js/src/dom/manipulator.js","../../js/src/util/config.js","../../js/src/base-component.js","../../js/src/dom/selector-engine.js","../../js/src/util/component-functions.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/util/swipe.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/@popperjs/core/lib/enums.js","../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js","../../node_modules/@popperjs/core/lib/utils/math.js","../../node_modules/@popperjs/core/lib/utils/userAgent.js","../../node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","../../node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","../../node_modules/@popperjs/core/lib/dom-utils/contains.js","../../node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","../../node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","../../node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","../../node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","../../node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","../../node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","../../node_modules/@popperjs/core/lib/utils/within.js","../../node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","../../node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","../../node_modules/@popperjs/core/lib/utils/expandToHashMap.js","../../node_modules/@popperjs/core/lib/modifiers/arrow.js","../../node_modules/@popperjs/core/lib/utils/getVariation.js","../../node_modules/@popperjs/core/lib/modifiers/computeStyles.js","../../node_modules/@popperjs/core/lib/modifiers/eventListeners.js","../../node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","../../node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","../../node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","../../node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","../../node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","../../node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","../../node_modules/@popperjs/core/lib/utils/rectToClientRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","../../node_modules/@popperjs/core/lib/utils/computeOffsets.js","../../node_modules/@popperjs/core/lib/utils/detectOverflow.js","../../node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","../../node_modules/@popperjs/core/lib/modifiers/flip.js","../../node_modules/@popperjs/core/lib/modifiers/hide.js","../../node_modules/@popperjs/core/lib/modifiers/offset.js","../../node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","../../node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","../../node_modules/@popperjs/core/lib/utils/getAltAxis.js","../../node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","../../node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","../../node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","../../node_modules/@popperjs/core/lib/utils/orderModifiers.js","../../node_modules/@popperjs/core/lib/createPopper.js","../../node_modules/@popperjs/core/lib/utils/debounce.js","../../node_modules/@popperjs/core/lib/utils/mergeByName.js","../../node_modules/@popperjs/core/lib/popper-lite.js","../../node_modules/@popperjs/core/lib/popper.js","../../js/src/dropdown.js","../../js/src/util/scrollbar.js","../../js/src/util/backdrop.js","../../js/src/util/focustrap.js","../../js/src/modal.js","../../js/src/offcanvas.js","../../js/src/util/sanitizer.js","../../js/src/util/template-factory.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js","../../js/index.umd.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1_000_000\nconst MILLISECONDS_MULTIPLIER = 1000\nconst TRANSITION_END = 'transitionend'\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`)\n }\n\n return selector\n}\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`\n }\n\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase()\n}\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID)\n } while (document.getElementById(prefix))\n\n return prefix\n}\n\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0\n }\n\n // Get transition-duration of the element\n let { transitionDuration, transitionDelay } = window.getComputedStyle(element)\n\n const floatTransitionDuration = Number.parseFloat(transitionDuration)\n const floatTransitionDelay = Number.parseFloat(transitionDelay)\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0]\n transitionDelay = transitionDelay.split(',')[0]\n\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER\n}\n\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END))\n}\n\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false\n }\n\n if (typeof object.jquery !== 'undefined') {\n object = object[0]\n }\n\n return typeof object.nodeType !== 'undefined'\n}\n\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object\n }\n\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object))\n }\n\n return null\n}\n\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false\n }\n\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])')\n\n if (!closedDetails) {\n return elementIsVisible\n }\n\n if (closedDetails !== element) {\n const summary = element.closest('summary')\n if (summary && summary.parentNode !== closedDetails) {\n return false\n }\n\n if (summary === null) {\n return false\n }\n }\n\n return elementIsVisible\n}\n\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true\n }\n\n if (element.classList.contains('disabled')) {\n return true\n }\n\n if (typeof element.disabled !== 'undefined') {\n return element.disabled\n }\n\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'\n}\n\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode()\n return root instanceof ShadowRoot ? root : null\n }\n\n if (element instanceof ShadowRoot) {\n return element\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null\n }\n\n return findShadowRoot(element.parentNode)\n}\n\nconst noop = () => {}\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight // eslint-disable-line no-unused-expressions\n}\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery\n }\n\n return null\n}\n\nconst DOMContentLoadedCallbacks = []\n\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback()\n }\n })\n }\n\n DOMContentLoadedCallbacks.push(callback)\n } else {\n callback()\n }\n}\n\nconst isRTL = () => document.documentElement.dir === 'rtl'\n\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery()\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME\n const JQUERY_NO_CONFLICT = $.fn[name]\n $.fn[name] = plugin.jQueryInterface\n $.fn[name].Constructor = plugin\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT\n return plugin.jQueryInterface\n }\n }\n })\n}\n\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue\n}\n\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback)\n return\n }\n\n const durationPadding = 5\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding\n\n let called = false\n\n const handler = ({ target }) => {\n if (target !== transitionElement) {\n return\n }\n\n called = true\n transitionElement.removeEventListener(TRANSITION_END, handler)\n execute(callback)\n }\n\n transitionElement.addEventListener(TRANSITION_END, handler)\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement)\n }\n }, emulatedDuration)\n}\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length\n let index = list.indexOf(activeElement)\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]\n }\n\n index += shouldGetNext ? 1 : -1\n\n if (isCycleAllowed) {\n index = (index + listLength) % listLength\n }\n\n return list[Math.max(0, Math.min(index, listLength - 1))]\n}\n\nexport {\n defineJQueryPlugin,\n execute,\n executeAfterTransition,\n findShadowRoot,\n getElement,\n getjQuery,\n getNextActiveElement,\n getTransitionDurationFromElement,\n getUID,\n isDisabled,\n isElement,\n isRTL,\n isVisible,\n noop,\n onDOMContentLoaded,\n parseSelector,\n reflow,\n triggerTransitionEnd,\n toType\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { getjQuery } from '../util/index.js'\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/\nconst stripNameRegex = /\\..*/\nconst stripUidRegex = /::\\d+$/\nconst eventRegistry = {} // Events storage\nlet uidEvent = 1\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n}\n\nconst nativeEvents = new Set([\n 'click',\n 'dblclick',\n 'mouseup',\n 'mousedown',\n 'contextmenu',\n 'mousewheel',\n 'DOMMouseScroll',\n 'mouseover',\n 'mouseout',\n 'mousemove',\n 'selectstart',\n 'selectend',\n 'keydown',\n 'keypress',\n 'keyup',\n 'orientationchange',\n 'touchstart',\n 'touchmove',\n 'touchend',\n 'touchcancel',\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'pointerleave',\n 'pointercancel',\n 'gesturestart',\n 'gesturechange',\n 'gestureend',\n 'focus',\n 'blur',\n 'change',\n 'reset',\n 'select',\n 'submit',\n 'focusin',\n 'focusout',\n 'load',\n 'unload',\n 'beforeunload',\n 'resize',\n 'move',\n 'DOMContentLoaded',\n 'readystatechange',\n 'error',\n 'abort',\n 'scroll'\n])\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return (uid && `${uid}::${uidEvent++}`) || element.uidEvent || uidEvent++\n}\n\nfunction getElementEvents(element) {\n const uid = makeEventUid(element)\n\n element.uidEvent = uid\n eventRegistry[uid] = eventRegistry[uid] || {}\n\n return eventRegistry[uid]\n}\n\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, { delegateTarget: element })\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn)\n }\n\n return fn.apply(element, [event])\n }\n}\n\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector)\n\n for (let { target } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue\n }\n\n hydrateObj(event, { delegateTarget: target })\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn)\n }\n\n return fn.apply(target, [event])\n }\n }\n }\n}\n\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events)\n .find(event => event.callable === callable && event.delegationSelector === delegationSelector)\n}\n\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string'\n // todo: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : (handler || delegationFunction)\n let typeEvent = getTypeEvent(originalTypeEvent)\n\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent\n }\n\n return [isDelegated, callable, typeEvent]\n}\n\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return\n }\n\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || (event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget))) {\n return fn.call(this, event)\n }\n }\n }\n\n callable = wrapFunction(callable)\n }\n\n const events = getElementEvents(element)\n const handlers = events[typeEvent] || (events[typeEvent] = {})\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null)\n\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff\n\n return\n }\n\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''))\n const fn = isDelegated ?\n bootstrapDelegationHandler(element, handler, callable) :\n bootstrapHandler(element, callable)\n\n fn.delegationSelector = isDelegated ? handler : null\n fn.callable = callable\n fn.oneOff = oneOff\n fn.uidEvent = uid\n handlers[uid] = fn\n\n element.addEventListener(typeEvent, fn, isDelegated)\n}\n\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector)\n\n if (!fn) {\n return\n }\n\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector))\n delete events[typeEvent][fn.uidEvent]\n}\n\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {}\n\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n }\n }\n}\n\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '')\n return customEvents[event] || event\n}\n\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false)\n },\n\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true)\n },\n\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return\n }\n\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction)\n const inNamespace = typeEvent !== originalTypeEvent\n const events = getElementEvents(element)\n const storeElementEvent = events[typeEvent] || {}\n const isNamespace = originalTypeEvent.startsWith('.')\n\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return\n }\n\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null)\n return\n }\n\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1))\n }\n }\n\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '')\n\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector)\n }\n }\n },\n\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null\n }\n\n const $ = getjQuery()\n const typeEvent = getTypeEvent(event)\n const inNamespace = event !== typeEvent\n\n let jQueryEvent = null\n let bubbles = true\n let nativeDispatch = true\n let defaultPrevented = false\n\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args)\n\n $(element).trigger(jQueryEvent)\n bubbles = !jQueryEvent.isPropagationStopped()\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped()\n defaultPrevented = jQueryEvent.isDefaultPrevented()\n }\n\n let evt = new Event(event, { bubbles, cancelable: true })\n evt = hydrateObj(evt, args)\n\n if (defaultPrevented) {\n evt.preventDefault()\n }\n\n if (nativeDispatch) {\n element.dispatchEvent(evt)\n }\n\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault()\n }\n\n return evt\n }\n}\n\nfunction hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n try {\n obj[key] = value\n } catch {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value\n }\n })\n }\n }\n\n return obj\n}\n\nexport default EventHandler\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true\n }\n\n if (value === 'false') {\n return false\n }\n\n if (value === Number(value).toString()) {\n return Number(value)\n }\n\n if (value === '' || value === 'null') {\n return null\n }\n\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(decodeURIComponent(value))\n } catch {\n return value\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)\n attributes[pureKey] = normalizeData(element.dataset[key])\n }\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n }\n}\n\nexport default Manipulator\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { isElement, toType } from './index.js'\nimport Manipulator from '../dom/manipulator.js'\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {}\n }\n\n static get DefaultType() {\n return {}\n }\n\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!')\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n _configAfterMerge(config) {\n return config\n }\n\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n }\n }\n\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property]\n const valueType = isElement(value) ? 'element' : toType(value)\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(\n `${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`\n )\n }\n }\n }\n}\n\nexport default Config\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.0-alpha2'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { isDisabled, isVisible, parseSelector } from '../util/index.js'\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target')\n\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href')\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {\n return null\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`\n }\n\n selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null\n }\n\n return parseSelector(selector)\n}\n\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector))\n },\n\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector)\n },\n\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector))\n },\n\n parents(element, selector) {\n const parents = []\n let ancestor = element.parentNode.closest(selector)\n\n while (ancestor) {\n parents.push(ancestor)\n ancestor = ancestor.parentNode.closest(selector)\n }\n\n return parents\n },\n\n prev(element, selector) {\n let previous = element.previousElementSibling\n\n while (previous) {\n if (previous.matches(selector)) {\n return [previous]\n }\n\n previous = previous.previousElementSibling\n }\n\n return []\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling\n\n while (next) {\n if (next.matches(selector)) {\n return [next]\n }\n\n next = next.nextElementSibling\n }\n\n return []\n },\n\n focusableChildren(element) {\n const focusables = [\n 'a',\n 'button',\n 'input',\n 'textarea',\n 'select',\n 'details',\n '[tabindex]',\n '[contenteditable=\"true\"]'\n ].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',')\n\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el))\n },\n\n getSelectorFromElement(element) {\n const selector = getSelector(element)\n\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null\n }\n\n return null\n },\n\n getElementFromSelector(element) {\n const selector = getSelector(element)\n\n return selector ? SelectorEngine.findOne(selector) : null\n },\n\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element)\n\n return selector ? SelectorEngine.find(selector) : []\n }\n}\n\nexport default SelectorEngine\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport { isDisabled } from './index.js'\nimport SelectorEngine from '../dom/selector-engine.js'\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`\n const name = component.NAME\n\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`)\n const instance = component.getOrCreateInstance(target)\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]()\n })\n}\n\nexport {\n enableDismissTrigger\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin } from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport BaseComponent from './base-component.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin } from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport BaseComponent from './base-component.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this)\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Config from './config.js'\nimport EventHandler from '../dom/event-handler.js'\nimport { execute } from './index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'swipe'\nconst EVENT_KEY = '.bs.swipe'\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY}`\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY}`\nconst POINTER_TYPE_TOUCH = 'touch'\nconst POINTER_TYPE_PEN = 'pen'\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event'\nconst SWIPE_THRESHOLD = 40\n\nconst Default = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n}\n\nconst DefaultType = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n}\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super()\n this._element = element\n\n if (!element || !Swipe.isSupported()) {\n return\n }\n\n this._config = this._getConfig(config)\n this._deltaX = 0\n this._supportPointerEvents = Boolean(window.PointerEvent)\n this._initEvents()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY)\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX\n\n return\n }\n\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX\n }\n }\n\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX\n }\n\n this._handleSwipe()\n execute(this._config.endCallback)\n }\n\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ?\n 0 :\n event.touches[0].clientX - this._deltaX\n }\n\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX)\n\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return\n }\n\n const direction = absDeltaX / this._deltaX\n\n this._deltaX = 0\n\n if (!direction) {\n return\n }\n\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback)\n }\n\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event))\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event))\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT)\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event))\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event))\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event))\n }\n }\n\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0\n }\n}\n\nexport default Swipe\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n defineJQueryPlugin,\n getNextActiveElement,\n isRTL,\n isVisible,\n reflow,\n triggerTransitionEnd\n} from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Swipe from './util/swipe.js'\nimport BaseComponent from './base-component.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'carousel'\nconst DATA_KEY = 'bs.carousel'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ARROW_LEFT_KEY = 'ArrowLeft'\nconst ARROW_RIGHT_KEY = 'ArrowRight'\nconst TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next'\nconst ORDER_PREV = 'prev'\nconst DIRECTION_LEFT = 'left'\nconst DIRECTION_RIGHT = 'right'\n\nconst EVENT_SLIDE = `slide${EVENT_KEY}`\nconst EVENT_SLID = `slid${EVENT_KEY}`\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY}`\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_CAROUSEL = 'carousel'\nconst CLASS_NAME_ACTIVE = 'active'\nconst CLASS_NAME_SLIDE = 'slide'\nconst CLASS_NAME_END = 'carousel-item-end'\nconst CLASS_NAME_START = 'carousel-item-start'\nconst CLASS_NAME_NEXT = 'carousel-item-next'\nconst CLASS_NAME_PREV = 'carousel-item-prev'\n\nconst SELECTOR_ACTIVE = '.active'\nconst SELECTOR_ITEM = '.carousel-item'\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM\nconst SELECTOR_ITEM_IMG = '.carousel-item img'\nconst SELECTOR_INDICATORS = '.carousel-indicators'\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]'\n\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n}\n\nconst Default = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n}\n\nconst DefaultType = {\n interval: '(number|boolean)', // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._interval = null\n this._activeElement = null\n this._isSliding = false\n this.touchTimeout = null\n this._swipeHelper = null\n\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)\n this._addEventListeners()\n\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT)\n }\n\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next()\n }\n }\n\n prev() {\n this._slide(ORDER_PREV)\n }\n\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element)\n }\n\n this._clearInterval()\n }\n\n cycle() {\n this._clearInterval()\n this._updateInterval()\n\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval)\n }\n\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle())\n return\n }\n\n this.cycle()\n }\n\n to(index) {\n const items = this._getItems()\n if (index > items.length - 1 || index < 0) {\n return\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index))\n return\n }\n\n const activeIndex = this._getItemIndex(this._getActive())\n if (activeIndex === index) {\n return\n }\n\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV\n\n this._slide(order, items[index])\n }\n\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose()\n }\n\n super.dispose()\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval\n return config\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))\n }\n\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause())\n EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle())\n }\n\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners()\n }\n }\n\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault())\n }\n\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause()\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout)\n }\n\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval)\n }\n\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n }\n\n this._swipeHelper = new Swipe(this._element, swipeConfig)\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return\n }\n\n const direction = KEY_TO_DIRECTION[event.key]\n if (direction) {\n event.preventDefault()\n this._slide(this._directionToOrder(direction))\n }\n }\n\n _getItemIndex(element) {\n return this._getItems().indexOf(element)\n }\n\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return\n }\n\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement)\n\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE)\n activeIndicator.removeAttribute('aria-current')\n\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement)\n\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE)\n newActiveIndicator.setAttribute('aria-current', 'true')\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._getActive()\n\n if (!element) {\n return\n }\n\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10)\n\n this._config.interval = elementInterval || this._config.defaultInterval\n }\n\n _slide(order, element = null) {\n if (this._isSliding) {\n return\n }\n\n const activeElement = this._getActive()\n const isNext = order === ORDER_NEXT\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap)\n\n if (nextElement === activeElement) {\n return\n }\n\n const nextElementIndex = this._getItemIndex(nextElement)\n\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n })\n }\n\n const slideEvent = triggerEvent(EVENT_SLIDE)\n\n if (slideEvent.defaultPrevented) {\n return\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // todo: change tests that use empty divs to avoid this check\n return\n }\n\n const isCycling = Boolean(this._interval)\n this.pause()\n\n this._isSliding = true\n\n this._setActiveIndicatorElement(nextElementIndex)\n this._activeElement = nextElement\n\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV\n\n nextElement.classList.add(orderClassName)\n\n reflow(nextElement)\n\n activeElement.classList.add(directionalClassName)\n nextElement.classList.add(directionalClassName)\n\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName)\n nextElement.classList.add(CLASS_NAME_ACTIVE)\n\n activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName)\n\n this._isSliding = false\n\n triggerEvent(EVENT_SLID)\n }\n\n this._queueCallback(completeCallBack, activeElement, this._isAnimated())\n\n if (isCycling) {\n this.cycle()\n }\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE)\n }\n\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)\n }\n\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element)\n }\n\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval)\n this._interval = null\n }\n }\n\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT\n }\n\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV\n }\n\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT\n }\n\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config)\n\n if (typeof config === 'number') {\n data.to(config)\n return\n }\n\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this)\n\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return\n }\n\n event.preventDefault()\n\n const carousel = Carousel.getOrCreateInstance(target)\n const slideIndex = this.getAttribute('data-bs-slide-to')\n\n if (slideIndex) {\n carousel.to(slideIndex)\n carousel._maybeEnableCycle()\n return\n }\n\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next()\n carousel._maybeEnableCycle()\n return\n }\n\n carousel.prev()\n carousel._maybeEnableCycle()\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE)\n\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel)\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel)\n\nexport default Carousel\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n defineJQueryPlugin,\n getElement,\n reflow\n} from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport BaseComponent from './base-component.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'collapse'\nconst DATA_KEY = 'bs.collapse'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_COLLAPSE = 'collapse'\nconst CLASS_NAME_COLLAPSING = 'collapsing'\nconst CLASS_NAME_COLLAPSED = 'collapsed'\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal'\n\nconst WIDTH = 'width'\nconst HEIGHT = 'height'\n\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"collapse\"]'\n\nconst Default = {\n parent: null,\n toggle: true\n}\n\nconst DefaultType = {\n parent: '(null|element)',\n toggle: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isTransitioning = false\n this._triggerArray = []\n\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE)\n\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem)\n const filterElement = SelectorEngine.find(selector)\n .filter(foundElement => foundElement === this._element)\n\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem)\n }\n }\n\n this._initializeChildren()\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown())\n }\n\n if (this._config.toggle) {\n this.toggle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide()\n } else {\n this.show()\n }\n }\n\n show() {\n if (this._isTransitioning || this._isShown()) {\n return\n }\n\n let activeChildren = []\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES)\n .filter(element => element !== this._element)\n .map(element => Collapse.getOrCreateInstance(element, { toggle: false }))\n }\n\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW)\n if (startEvent.defaultPrevented) {\n return\n }\n\n for (const activeInstance of activeChildren) {\n activeInstance.hide()\n }\n\n const dimension = this._getDimension()\n\n this._element.classList.remove(CLASS_NAME_COLLAPSE)\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n\n this._element.style[dimension] = 0\n\n this._addAriaAndCollapsedClass(this._triggerArray, true)\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n this._element.style[dimension] = ''\n\n EventHandler.trigger(this._element, EVENT_SHOWN)\n }\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)\n const scrollSize = `scroll${capitalizedDimension}`\n\n this._queueCallback(complete, this._element, true)\n this._element.style[dimension] = `${this._element[scrollSize]}px`\n }\n\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n if (startEvent.defaultPrevented) {\n return\n }\n\n const dimension = this._getDimension()\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_COLLAPSING)\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW)\n\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger)\n\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false)\n }\n }\n\n this._isTransitioning = true\n\n const complete = () => {\n this._isTransitioning = false\n this._element.classList.remove(CLASS_NAME_COLLAPSING)\n this._element.classList.add(CLASS_NAME_COLLAPSE)\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._element.style[dimension] = ''\n\n this._queueCallback(complete, this._element, true)\n }\n\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW)\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle) // Coerce string values\n config.parent = getElement(config.parent)\n return config\n }\n\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT\n }\n\n _initializeChildren() {\n if (!this._config.parent) {\n return\n }\n\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE)\n\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element)\n\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected))\n }\n }\n }\n\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent)\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element))\n }\n\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return\n }\n\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen)\n element.setAttribute('aria-expanded', isOpen)\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {}\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false\n }\n\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config)\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n // preventDefault only for
elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {\n event.preventDefault()\n }\n\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, { toggle: false }).toggle()\n }\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse)\n\nexport default Collapse\n","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!isHTMLElement(arrowElement)) {\n console.error(['Popper: \"arrow\" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(['Popper: \"arrow\" modifier\\'s `element` must be a child of the popper', 'element.'].join(' '));\n }\n\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref) {\n var x = _ref.x,\n y = _ref.y;\n var win = window;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n\n if (process.env.NODE_ENV !== \"production\") {\n var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';\n\n if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {\n return transitionProperty.indexOf(property) >= 0;\n })) {\n console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: \"transform\", \"top\", \"right\", \"bottom\", \"left\".', '\\n\\n', 'Disable the \"computeStyles\" modifier\\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\\n\\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));\n }\n }\n\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, \"auto\" cannot be used to allow \"bottom-start\".', 'Use \"auto-start\" instead.'].join(' '));\n }\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport getComputedStyle from \"./dom-utils/getComputedStyle.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport validateModifiers from \"./utils/validateModifiers.js\";\nimport uniqueBy from \"./utils/uniqueBy.js\";\nimport getBasePlacement from \"./utils/getBasePlacement.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nimport { auto } from \"./enums.js\";\nvar INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';\nvar INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n }); // Validate the provided modifiers so that the consumer will get warned\n // if one of the modifiers is invalid for any reason\n\n if (process.env.NODE_ENV !== \"production\") {\n var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {\n var name = _ref.name;\n return name;\n });\n validateModifiers(modifiers);\n\n if (getBasePlacement(state.options.placement) === auto) {\n var flipModifier = state.orderedModifiers.find(function (_ref2) {\n var name = _ref2.name;\n return name === 'flip';\n });\n\n if (!flipModifier) {\n console.error(['Popper: \"auto\" placements require the \"flip\" modifier be', 'present and enabled to work.'].join(' '));\n }\n }\n\n var _getComputedStyle = getComputedStyle(popper),\n marginTop = _getComputedStyle.marginTop,\n marginRight = _getComputedStyle.marginRight,\n marginBottom = _getComputedStyle.marginBottom,\n marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can\n // cause bugs with positioning, so we'll warn the consumer\n\n\n if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {\n return parseFloat(margin);\n })) {\n console.warn(['Popper: CSS \"margin\" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));\n }\n }\n\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(INVALID_ELEMENT_ERROR);\n }\n\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n var __debug_loops__ = 0;\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (process.env.NODE_ENV !== \"production\") {\n __debug_loops__ += 1;\n\n if (__debug_loops__ > 100) {\n console.error(INFINITE_LOOP_ERROR);\n break;\n }\n }\n\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(INVALID_ELEMENT_ERROR);\n }\n\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref3) {\n var name = _ref3.name,\n _ref3$options = _ref3.options,\n options = _ref3$options === void 0 ? {} : _ref3$options,\n effect = _ref3.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport {\n defineJQueryPlugin,\n execute,\n getElement,\n getNextActiveElement,\n isDisabled,\n isElement,\n isRTL,\n isVisible,\n noop\n} from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport BaseComponent from './base-component.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'dropdown'\nconst DATA_KEY = 'bs.dropdown'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst ESCAPE_KEY = 'Escape'\nconst TAB_KEY = 'Tab'\nconst ARROW_UP_KEY = 'ArrowUp'\nconst ARROW_DOWN_KEY = 'ArrowDown'\nconst RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_DROPUP = 'dropup'\nconst CLASS_NAME_DROPEND = 'dropend'\nconst CLASS_NAME_DROPSTART = 'dropstart'\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center'\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)'\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`\nconst SELECTOR_MENU = '.dropdown-menu'\nconst SELECTOR_NAVBAR = '.navbar'\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav'\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'\n\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'\nconst PLACEMENT_TOPCENTER = 'top'\nconst PLACEMENT_BOTTOMCENTER = 'bottom'\n\nconst Default = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n}\n\nconst DefaultType = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n}\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._popper = null\n this._parent = this._element.parentNode // dropdown wrapper\n // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] ||\n SelectorEngine.prev(this._element, SELECTOR_MENU)[0] ||\n SelectorEngine.findOne(SELECTOR_MENU, this._parent)\n this._inNavbar = this._detectNavbar()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show()\n }\n\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, relatedTarget)\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._createPopper()\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop)\n }\n }\n\n this._element.focus()\n this._element.setAttribute('aria-expanded', true)\n\n this._menu.classList.add(CLASS_NAME_SHOW)\n this._element.classList.add(CLASS_NAME_SHOW)\n EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget)\n }\n\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n }\n\n this._completeHide(relatedTarget)\n }\n\n dispose() {\n if (this._popper) {\n this._popper.destroy()\n }\n\n super.dispose()\n }\n\n update() {\n this._inNavbar = this._detectNavbar()\n if (this._popper) {\n this._popper.update()\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget)\n if (hideEvent.defaultPrevented) {\n return\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop)\n }\n }\n\n if (this._popper) {\n this._popper.destroy()\n }\n\n this._menu.classList.remove(CLASS_NAME_SHOW)\n this._element.classList.remove(CLASS_NAME_SHOW)\n this._element.setAttribute('aria-expanded', 'false')\n Manipulator.removeDataAttribute(this._menu, 'popper')\n EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)\n }\n\n _getConfig(config) {\n config = super._getConfig(config)\n\n if (typeof config.reference === 'object' && !isElement(config.reference) &&\n typeof config.reference.getBoundingClientRect !== 'function'\n ) {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`)\n }\n\n return config\n }\n\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)')\n }\n\n let referenceElement = this._element\n\n if (this._config.reference === 'parent') {\n referenceElement = this._parent\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference)\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference\n }\n\n const popperConfig = this._getPopperConfig()\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)\n }\n\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW)\n }\n\n _getPlacement() {\n const parentDropdown = this._parent\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP\n }\n\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM\n }\n\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null\n }\n\n _getOffset() {\n const { offset } = this._config\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10))\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element)\n }\n\n return offset\n }\n\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n },\n {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n }\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static') // todo:v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }]\n }\n\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n }\n }\n\n _selectMenuItem({ key, target }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element))\n\n if (!items.length) {\n return\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || (event.type === 'keyup' && event.key !== TAB_KEY)) {\n return\n }\n\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN)\n\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle)\n if (!context || context._config.autoClose === false) {\n continue\n }\n\n const composedPath = event.composedPath()\n const isMenuTarget = composedPath.includes(context._menu)\n if (\n composedPath.includes(context._element) ||\n (context._config.autoClose === 'inside' && !isMenuTarget) ||\n (context._config.autoClose === 'outside' && isMenuTarget)\n ) {\n continue\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && ((event.type === 'keyup' && event.key === TAB_KEY) || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue\n }\n\n const relatedTarget = { relatedTarget: context._element }\n\n if (event.type === 'click') {\n relatedTarget.clickEvent = event\n }\n\n context._completeHide(relatedTarget)\n }\n }\n\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName)\n const isEscapeEvent = event.key === ESCAPE_KEY\n const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)\n\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return\n }\n\n if (isInput && !isEscapeEvent) {\n return\n }\n\n event.preventDefault()\n\n // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ?\n this :\n (SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] ||\n SelectorEngine.next(this, SELECTOR_DATA_TOGGLE)[0] ||\n SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode))\n\n const instance = Dropdown.getOrCreateInstance(getToggleButton)\n\n if (isUpOrDownEvent) {\n event.stopPropagation()\n instance.show()\n instance._selectMenuItem(event)\n return\n }\n\n if (instance._isShown()) { // else is escape and we check if it is shown\n event.stopPropagation()\n instance.hide()\n getToggleButton.focus()\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler)\nEventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus)\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n event.preventDefault()\n Dropdown.getOrCreateInstance(this).toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown)\n\nexport default Dropdown\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Manipulator from '../dom/manipulator.js'\nimport { isElement } from './index.js'\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'\nconst SELECTOR_STICKY_CONTENT = '.sticky-top'\nconst PROPERTY_PADDING = 'padding-right'\nconst PROPERTY_MARGIN = 'margin-right'\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth\n return Math.abs(window.innerWidth - documentWidth)\n }\n\n hide() {\n const width = this.getWidth()\n this._disableOverFlow()\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width)\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width)\n }\n\n reset() {\n this._resetElementAttributes(this._element, 'overflow')\n this._resetElementAttributes(this._element, PROPERTY_PADDING)\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING)\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN)\n }\n\n isOverflowing() {\n return this.getWidth() > 0\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow')\n this._element.style.overflow = 'hidden'\n }\n\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth()\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return\n }\n\n this._saveInitialAttribute(element, styleProperty)\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty)\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`)\n }\n\n this._applyManipulationCallback(selector, manipulationCallBack)\n }\n\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty)\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue)\n }\n }\n\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty)\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty)\n return\n }\n\n Manipulator.removeDataAttribute(element, styleProperty)\n element.style.setProperty(styleProperty, value)\n }\n\n this._applyManipulationCallback(selector, manipulationCallBack)\n }\n\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector)\n return\n }\n\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel)\n }\n }\n}\n\nexport default ScrollBarHelper\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport { execute, executeAfterTransition, getElement, reflow } from './index.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'backdrop'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`\n\nconst Default = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true, // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n}\n\nconst DefaultType = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n}\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isAppended = false\n this._element = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback)\n return\n }\n\n this._append()\n\n const element = this._getElement()\n if (this._config.isAnimated) {\n reflow(element)\n }\n\n element.classList.add(CLASS_NAME_SHOW)\n\n this._emulateAnimation(() => {\n execute(callback)\n })\n }\n\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback)\n return\n }\n\n this._getElement().classList.remove(CLASS_NAME_SHOW)\n\n this._emulateAnimation(() => {\n this.dispose()\n execute(callback)\n })\n }\n\n dispose() {\n if (!this._isAppended) {\n return\n }\n\n EventHandler.off(this._element, EVENT_MOUSEDOWN)\n\n this._element.remove()\n this._isAppended = false\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div')\n backdrop.className = this._config.className\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE)\n }\n\n this._element = backdrop\n }\n\n return this._element\n }\n\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement)\n return config\n }\n\n _append() {\n if (this._isAppended) {\n return\n }\n\n const element = this._getElement()\n this._config.rootElement.append(element)\n\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback)\n })\n\n this._isAppended = true\n }\n\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated)\n }\n}\n\nexport default Backdrop\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n}\n\nconst DefaultType = {\n autofocus: 'boolean',\n trapElement: 'element'\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isActive = false\n this._lastTabNavDirection = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return\n }\n\n if (this._config.autofocus) {\n this._config.trapElement.focus()\n }\n\n EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))\n\n this._isActive = true\n }\n\n deactivate() {\n if (!this._isActive) {\n return\n }\n\n this._isActive = false\n EventHandler.off(document, EVENT_KEY)\n }\n\n // Private\n _handleFocusin(event) {\n const { trapElement } = this._config\n\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return\n }\n\n const elements = SelectorEngine.focusableChildren(trapElement)\n\n if (elements.length === 0) {\n trapElement.focus()\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus()\n } else {\n elements[0].focus()\n }\n }\n\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return\n }\n\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n }\n}\n\nexport default FocusTrap\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin, isRTL, isVisible, reflow } from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport ScrollBarHelper from './util/scrollbar.js'\nimport BaseComponent from './base-component.js'\nimport Backdrop from './util/backdrop.js'\nimport FocusTrap from './util/focustrap.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'modal'\nconst DATA_KEY = 'bs.modal'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst ESCAPE_KEY = 'Escape'\n\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_OPEN = 'modal-open'\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_STATIC = 'modal-static'\n\nconst OPEN_SELECTOR = '.modal.show'\nconst SELECTOR_DIALOG = '.modal-dialog'\nconst SELECTOR_MODAL_BODY = '.modal-body'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"modal\"]'\n\nconst Default = {\n backdrop: true,\n focus: true,\n keyboard: true\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)\n this._backdrop = this._initializeBackDrop()\n this._focustrap = this._initializeFocusTrap()\n this._isShown = false\n this._isTransitioning = false\n this._scrollBar = new ScrollBarHelper()\n\n this._addEventListeners()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {\n relatedTarget\n })\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._isShown = true\n this._isTransitioning = true\n\n this._scrollBar.hide()\n\n document.body.classList.add(CLASS_NAME_OPEN)\n\n this._adjustDialog()\n\n this._backdrop.show(() => this._showElement(relatedTarget))\n }\n\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n if (hideEvent.defaultPrevented) {\n return\n }\n\n this._isShown = false\n this._isTransitioning = true\n this._focustrap.deactivate()\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())\n }\n\n dispose() {\n for (const htmlElement of [window, this._dialog]) {\n EventHandler.off(htmlElement, EVENT_KEY)\n }\n\n this._backdrop.dispose()\n this._focustrap.deactivate()\n super.dispose()\n }\n\n handleUpdate() {\n this._adjustDialog()\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n })\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n })\n }\n\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element)\n }\n\n this._element.style.display = 'block'\n this._element.removeAttribute('aria-hidden')\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n this._element.scrollTop = 0\n\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)\n if (modalBody) {\n modalBody.scrollTop = 0\n }\n\n reflow(this._element)\n\n this._element.classList.add(CLASS_NAME_SHOW)\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate()\n }\n\n this._isTransitioning = false\n EventHandler.trigger(this._element, EVENT_SHOWN, {\n relatedTarget\n })\n }\n\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated())\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return\n }\n\n if (this._config.keyboard) {\n this.hide()\n return\n }\n\n this._triggerBackdropTransition()\n })\n\n EventHandler.on(window, EVENT_RESIZE, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog()\n }\n })\n\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition()\n return\n }\n\n if (this._config.backdrop) {\n this.hide()\n }\n })\n })\n }\n\n _hideModal() {\n this._element.style.display = 'none'\n this._element.setAttribute('aria-hidden', true)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n this._isTransitioning = false\n\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN)\n this._resetAdjustments()\n this._scrollBar.reset()\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n })\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE)\n }\n\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n if (hideEvent.defaultPrevented) {\n return\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n const initialOverflowY = this._element.style.overflowY\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return\n }\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden'\n }\n\n this._element.classList.add(CLASS_NAME_STATIC)\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC)\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY\n }, this._dialog)\n }, this._dialog)\n\n this._element.focus()\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight\n const scrollbarWidth = this._scrollBar.getWidth()\n const isBodyOverflowing = scrollbarWidth > 0\n\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight'\n this._element.style[property] = `${scrollbarWidth}px`\n }\n\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft'\n this._element.style[property] = `${scrollbarWidth}px`\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = ''\n this._element.style.paddingRight = ''\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](relatedTarget)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this)\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n EventHandler.one(target, EVENT_SHOW, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return\n }\n\n EventHandler.one(target, EVENT_HIDDEN, () => {\n if (isVisible(this)) {\n this.focus()\n }\n })\n })\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide()\n }\n\n const data = Modal.getOrCreateInstance(target)\n\n data.toggle(this)\n})\n\nenableDismissTrigger(Modal)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal)\n\nexport default Modal\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport {\n defineJQueryPlugin,\n isDisabled,\n isVisible\n} from './util/index.js'\nimport ScrollBarHelper from './util/scrollbar.js'\nimport EventHandler from './dom/event-handler.js'\nimport BaseComponent from './base-component.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport Backdrop from './util/backdrop.js'\nimport FocusTrap from './util/focustrap.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'offcanvas'\nconst DATA_KEY = 'bs.offcanvas'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\nconst ESCAPE_KEY = 'Escape'\n\nconst CLASS_NAME_SHOW = 'show'\nconst CLASS_NAME_SHOWING = 'showing'\nconst CLASS_NAME_HIDING = 'hiding'\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop'\nconst OPEN_SELECTOR = '.offcanvas.show'\n\nconst EVENT_SHOW = `show${EVENT_KEY}`\nconst EVENT_SHOWN = `shown${EVENT_KEY}`\nconst EVENT_HIDE = `hide${EVENT_KEY}`\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`\nconst EVENT_RESIZE = `resize${EVENT_KEY}`\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`\n\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"offcanvas\"]'\n\nconst Default = {\n backdrop: true,\n keyboard: true,\n scroll: false\n}\n\nconst DefaultType = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n}\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n this._isShown = false\n this._backdrop = this._initializeBackDrop()\n this._focustrap = this._initializeFocusTrap()\n this._addEventListeners()\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget)\n }\n\n show(relatedTarget) {\n if (this._isShown) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { relatedTarget })\n\n if (showEvent.defaultPrevented) {\n return\n }\n\n this._isShown = true\n this._backdrop.show()\n\n if (!this._config.scroll) {\n new ScrollBarHelper().hide()\n }\n\n this._element.setAttribute('aria-modal', true)\n this._element.setAttribute('role', 'dialog')\n this._element.classList.add(CLASS_NAME_SHOWING)\n\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate()\n }\n\n this._element.classList.add(CLASS_NAME_SHOW)\n this._element.classList.remove(CLASS_NAME_SHOWING)\n EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget })\n }\n\n this._queueCallback(completeCallBack, this._element, true)\n }\n\n hide() {\n if (!this._isShown) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)\n\n if (hideEvent.defaultPrevented) {\n return\n }\n\n this._focustrap.deactivate()\n this._element.blur()\n this._isShown = false\n this._element.classList.add(CLASS_NAME_HIDING)\n this._backdrop.hide()\n\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_HIDING)\n this._element.removeAttribute('aria-modal')\n this._element.removeAttribute('role')\n\n if (!this._config.scroll) {\n new ScrollBarHelper().reset()\n }\n\n EventHandler.trigger(this._element, EVENT_HIDDEN)\n }\n\n this._queueCallback(completeCallback, this._element, true)\n }\n\n dispose() {\n this._backdrop.dispose()\n this._focustrap.deactivate()\n super.dispose()\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n return\n }\n\n this.hide()\n }\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop)\n\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n })\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n })\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return\n }\n\n if (this._config.keyboard) {\n this.hide()\n return\n }\n\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)\n })\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this)\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault()\n }\n\n if (isDisabled(this)) {\n return\n }\n\n EventHandler.one(target, EVENT_HIDDEN, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus()\n }\n })\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR)\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide()\n }\n\n const data = Offcanvas.getOrCreateInstance(target)\n data.toggle(this)\n})\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show()\n }\n})\n\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide()\n }\n }\n})\n\nenableDismissTrigger(Offcanvas)\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas)\n\nexport default Offcanvas\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst uriAttributes = new Set([\n 'background',\n 'cite',\n 'href',\n 'itemtype',\n 'longdesc',\n 'poster',\n 'src',\n 'xlink:href'\n])\n\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i\n\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i\n\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n */\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i\n\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase()\n\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue))\n }\n\n return true\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp)\n .some(regex => regex.test(attributeName))\n}\n\nexport const DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n}\n\nexport function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml\n }\n\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml)\n }\n\n const domParser = new window.DOMParser()\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'))\n\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase()\n\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove()\n\n continue\n }\n\n const attributeList = [].concat(...element.attributes)\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])\n\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName)\n }\n }\n }\n\n return createdDocument.body.innerHTML\n}\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { DefaultAllowlist, sanitizeHtml } from './sanitizer.js'\nimport { execute, getElement, isElement } from './index.js'\nimport SelectorEngine from '../dom/selector-engine.js'\nimport Config from './config.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'TemplateFactory'\n\nconst Default = {\n allowList: DefaultAllowlist,\n content: {}, // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
'\n}\n\nconst DefaultType = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n}\n\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n}\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content)\n .map(config => this._resolvePossibleFunction(config))\n .filter(Boolean)\n }\n\n hasContent() {\n return this.getContent().length > 0\n }\n\n changeContent(content) {\n this._checkContent(content)\n this._config.content = { ...this._config.content, ...content }\n return this\n }\n\n toHtml() {\n const templateWrapper = document.createElement('div')\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template)\n\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector)\n }\n\n const template = templateWrapper.children[0]\n const extraClass = this._resolvePossibleFunction(this._config.extraClass)\n\n if (extraClass) {\n template.classList.add(...extraClass.split(' '))\n }\n\n return template\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config)\n this._checkContent(config.content)\n }\n\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({ selector, entry: content }, DefaultContentType)\n }\n }\n\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template)\n\n if (!templateElement) {\n return\n }\n\n content = this._resolvePossibleFunction(content)\n\n if (!content) {\n templateElement.remove()\n return\n }\n\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement)\n return\n }\n\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content)\n return\n }\n\n templateElement.textContent = content\n }\n\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg\n }\n\n _resolvePossibleFunction(arg) {\n return execute(arg, [this])\n }\n\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = ''\n templateElement.append(element)\n return\n }\n\n templateElement.textContent = element.textContent\n }\n}\n\nexport default TemplateFactory\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport * as Popper from '@popperjs/core'\nimport { defineJQueryPlugin, execute, findShadowRoot, getElement, getUID, isRTL, noop } from './util/index.js'\nimport { DefaultAllowlist } from './util/sanitizer.js'\nimport EventHandler from './dom/event-handler.js'\nimport Manipulator from './dom/manipulator.js'\nimport BaseComponent from './base-component.js'\nimport TemplateFactory from './util/template-factory.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'tooltip'\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn'])\n\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_MODAL = 'modal'\nconst CLASS_NAME_SHOW = 'show'\n\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner'\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`\n\nconst EVENT_MODAL_HIDE = 'hide.bs.modal'\n\nconst TRIGGER_HOVER = 'hover'\nconst TRIGGER_FOCUS = 'focus'\nconst TRIGGER_CLICK = 'click'\nconst TRIGGER_MANUAL = 'manual'\n\nconst EVENT_HIDE = 'hide'\nconst EVENT_HIDDEN = 'hidden'\nconst EVENT_SHOW = 'show'\nconst EVENT_SHOWN = 'shown'\nconst EVENT_INSERTED = 'inserted'\nconst EVENT_CLICK = 'click'\nconst EVENT_FOCUSIN = 'focusin'\nconst EVENT_FOCUSOUT = 'focusout'\nconst EVENT_MOUSEENTER = 'mouseenter'\nconst EVENT_MOUSELEAVE = 'mouseleave'\n\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n}\n\nconst Default = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 0],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
' +\n '
' +\n '
' +\n '
',\n title: '',\n trigger: 'hover focus'\n}\n\nconst DefaultType = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n}\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)')\n }\n\n super(element, config)\n\n // Private\n this._isEnabled = true\n this._timeout = 0\n this._isHovered = null\n this._activeTrigger = {}\n this._popper = null\n this._templateFactory = null\n this._newContent = null\n\n // Protected\n this.tip = null\n\n this._setListeners()\n\n if (!this._config.selector) {\n this._fixTitle()\n }\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n enable() {\n this._isEnabled = true\n }\n\n disable() {\n this._isEnabled = false\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled\n }\n\n toggle() {\n if (!this._isEnabled) {\n return\n }\n\n this._activeTrigger.click = !this._activeTrigger.click\n if (this._isShown()) {\n this._leave()\n return\n }\n\n this._enter()\n }\n\n dispose() {\n clearTimeout(this._timeout)\n\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'))\n }\n\n this._disposePopper()\n super.dispose()\n }\n\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements')\n }\n\n if (!(this._isWithContent() && this._isEnabled)) {\n return\n }\n\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW))\n const shadowRoot = findShadowRoot(this._element)\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element)\n\n if (showEvent.defaultPrevented || !isInTheDom) {\n return\n }\n\n // todo v6 remove this OR make it optional\n this._disposePopper()\n\n const tip = this._getTipElement()\n\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'))\n\n const { container } = this._config\n\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip)\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED))\n }\n\n this._popper = this._createPopper(tip)\n\n tip.classList.add(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop)\n }\n }\n\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN))\n\n if (this._isHovered === false) {\n this._leave()\n }\n\n this._isHovered = false\n }\n\n this._queueCallback(complete, this.tip, this._isAnimated())\n }\n\n hide() {\n if (!this._isShown()) {\n return\n }\n\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE))\n if (hideEvent.defaultPrevented) {\n return\n }\n\n const tip = this._getTipElement()\n tip.classList.remove(CLASS_NAME_SHOW)\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop)\n }\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false\n this._activeTrigger[TRIGGER_FOCUS] = false\n this._activeTrigger[TRIGGER_HOVER] = false\n this._isHovered = null // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return\n }\n\n if (!this._isHovered) {\n this._disposePopper()\n }\n\n this._element.removeAttribute('aria-describedby')\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN))\n }\n\n this._queueCallback(complete, this.tip, this._isAnimated())\n }\n\n update() {\n if (this._popper) {\n this._popper.update()\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle())\n }\n\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate())\n }\n\n return this.tip\n }\n\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml()\n\n // todo: remove this check on v6\n if (!tip) {\n return null\n }\n\n tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW)\n // todo: on v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`)\n\n const tipId = getUID(this.constructor.NAME).toString()\n\n tip.setAttribute('id', tipId)\n\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE)\n }\n\n return tip\n }\n\n setContent(content) {\n this._newContent = content\n if (this._isShown()) {\n this._disposePopper()\n this.show()\n }\n }\n\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content)\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n })\n }\n\n return this._templateFactory\n }\n\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n }\n }\n\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title')\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())\n }\n\n _isAnimated() {\n return this._config.animation || (this.tip && this.tip.classList.contains(CLASS_NAME_FADE))\n }\n\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW)\n }\n\n _createPopper(tip) {\n const placement = execute(this._config.placement, [this, tip, this._element])\n const attachment = AttachmentMap[placement.toUpperCase()]\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment))\n }\n\n _getOffset() {\n const { offset } = this._config\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10))\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element)\n }\n\n return offset\n }\n\n _resolvePossibleFunction(arg) {\n return execute(arg, [this._element])\n }\n\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [\n {\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n },\n {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n },\n {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n },\n {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n },\n {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement)\n }\n }\n ]\n }\n\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n }\n }\n\n _setListeners() {\n const triggers = this._config.trigger.split(' ')\n\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context.toggle()\n })\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ?\n this.constructor.eventName(EVENT_MOUSEENTER) :\n this.constructor.eventName(EVENT_FOCUSIN)\n const eventOut = trigger === TRIGGER_HOVER ?\n this.constructor.eventName(EVENT_MOUSELEAVE) :\n this.constructor.eventName(EVENT_FOCUSOUT)\n\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true\n context._enter()\n })\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event)\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =\n context._element.contains(event.relatedTarget)\n\n context._leave()\n })\n }\n }\n\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide()\n }\n }\n\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler)\n }\n\n _fixTitle() {\n const title = this._element.getAttribute('title')\n\n if (!title) {\n return\n }\n\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title)\n }\n\n this._element.setAttribute('data-bs-original-title', title) // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title')\n }\n\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true\n return\n }\n\n this._isHovered = true\n\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show()\n }\n }, this._config.delay.show)\n }\n\n _leave() {\n if (this._isWithActiveTrigger()) {\n return\n }\n\n this._isHovered = false\n\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide()\n }\n }, this._config.delay.hide)\n }\n\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout)\n this._timeout = setTimeout(handler, timeout)\n }\n\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true)\n }\n\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element)\n\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute]\n }\n }\n\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n }\n config = this._mergeConfigObj(config)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container)\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n }\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString()\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString()\n }\n\n return config\n }\n\n _getDelegateConfig() {\n const config = {}\n\n for (const [key, value] of Object.entries(this._config)) {\n if (this.constructor.Default[key] !== value) {\n config[key] = value\n }\n }\n\n config.selector = false\n config.trigger = 'manual'\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config\n }\n\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy()\n this._popper = null\n }\n\n if (this.tip) {\n this.tip.remove()\n this.tip = null\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip)\n\nexport default Tooltip\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin } from './util/index.js'\nimport Tooltip from './tooltip.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'popover'\n\nconst SELECTOR_TITLE = '.popover-header'\nconst SELECTOR_CONTENT = '.popover-body'\n\nconst Default = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
' +\n '
' +\n '

' +\n '
' +\n '
',\n trigger: 'click'\n}\n\nconst DefaultType = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n}\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent()\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n }\n }\n\n _getContent() {\n return this._resolvePossibleFunction(this._config.content)\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config]()\n })\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover)\n\nexport default Popover\n","/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport { defineJQueryPlugin, getElement, isDisabled, isVisible } from './util/index.js'\nimport EventHandler from './dom/event-handler.js'\nimport SelectorEngine from './dom/selector-engine.js'\nimport BaseComponent from './base-component.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'scrollspy'\nconst DATA_KEY = 'bs.scrollspy'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst EVENT_ACTIVATE = `activate${EVENT_KEY}`\nconst EVENT_CLICK = `click${EVENT_KEY}`\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`\n\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'\nconst CLASS_NAME_ACTIVE = 'active'\n\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]'\nconst SELECTOR_TARGET_LINKS = '[href]'\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'\nconst SELECTOR_NAV_LINKS = '.nav-link'\nconst SELECTOR_NAV_ITEMS = '.nav-item'\nconst SELECTOR_LIST_ITEMS = '.list-group-item'\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`\nconst SELECTOR_DROPDOWN = '.dropdown'\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'\n\nconst Default = {\n offset: null, // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n}\n\nconst DefaultType = {\n offset: '(number|null)', // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n}\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config)\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map()\n this._observableSections = new Map()\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element\n this._activeTarget = null\n this._observer = null\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n }\n this.refresh() // initialize\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables()\n this._maybeEnableSmoothScroll()\n\n if (this._observer) {\n this._observer.disconnect()\n } else {\n this._observer = this._getNewObserver()\n }\n\n for (const section of this._observableSections.values()) {\n this._observer.observe(section)\n }\n }\n\n dispose() {\n this._observer.disconnect()\n super.dispose()\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin\n\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value))\n }\n\n return config\n }\n\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK)\n\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash)\n if (observableSection) {\n event.preventDefault()\n const root = this._rootElement || window\n const height = observableSection.offsetTop - this._element.offsetTop\n if (root.scrollTo) {\n root.scrollTo({ top: height, behavior: 'smooth' })\n return\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height\n }\n })\n }\n\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n }\n\n return new IntersectionObserver(entries => this._observerCallback(entries), options)\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`)\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop\n this._process(targetElement(entry))\n }\n\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop\n this._previousScrollData.parentScrollTop = parentScrollTop\n\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null\n this._clearActiveClass(targetElement(entry))\n\n continue\n }\n\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry)\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return\n }\n\n continue\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry)\n }\n }\n }\n\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map()\n this._observableSections = new Map()\n\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target)\n\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue\n }\n\n const observableSection = SelectorEngine.findOne(anchor.hash, this._element)\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(anchor.hash, anchor)\n this._observableSections.set(anchor.hash, observableSection)\n }\n }\n }\n\n _process(target) {\n if (this._activeTarget === target) {\n return\n }\n\n this._clearActiveClass(this._config.target)\n this._activeTarget = target\n target.classList.add(CLASS_NAME_ACTIVE)\n this._activateParents(target)\n\n EventHandler.trigger(this._element, EVENT_ACTIVATE, { relatedTarget: target })\n }\n\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN))\n .classList.add(CLASS_NAME_ACTIVE)\n return\n }\n\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both
    and