brut 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +75 -69
- data/brut-css/package-lock.json +2 -2
- data/brut-css/package.json +1 -1
- data/brut-js/package-lock.json +2 -2
- data/brut-js/package.json +1 -1
- data/brut-js/specs/ConfirmSubmit.spec.js +32 -1
- data/brut-js/src/ConfirmSubmit.js +28 -7
- data/brutrb.com/images/tutorial/basic-form-with-violations.png +0 -0
- data/brutrb.com/images/tutorial/basic-form.png +0 -0
- data/brutrb.com/images/tutorial/initial-home-page.png +0 -0
- data/brutrb.com/images/tutorial/new-post-editor.png +0 -0
- data/brutrb.com/images/tutorial/new-post-home-page.png +0 -0
- data/brutrb.com/images/tutorial/styled-form-with-server-side-violations.png +0 -0
- data/brutrb.com/images/tutorial/styled-form-with-violations.png +0 -0
- data/brutrb.com/images/tutorial/styled-home-page-with-posts.png +0 -0
- data/brutrb.com/images/tutorial/styled-home-page.png +0 -0
- data/brutrb.com/images/tutorial/welcome-to-brut.png +0 -0
- data/brutrb.com/tutorial.md +1728 -3
- data/docs/404.html +2 -2
- data/docs/adrs.html +3 -3
- data/docs/ai.html +3 -3
- data/docs/api/Brut/BackEnd/SeedData.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +1 -1
- data/docs/api/Brut/BackEnd/Sidekiq.html +1 -1
- data/docs/api/Brut/BackEnd/Validators/FormValidator.html +1 -1
- data/docs/api/Brut/BackEnd/Validators.html +1 -1
- data/docs/api/Brut/BackEnd.html +1 -1
- data/docs/api/Brut/CLI/App.html +1 -1
- data/docs/api/Brut/CLI/AppRunner.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +1 -1
- data/docs/api/Brut/CLI/Apps/BuildAssets.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Create.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Drop.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Migrate.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Seed.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB/Status.html +1 -1
- data/docs/api/Brut/CLI/Apps/DB.html +1 -1
- data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +1 -1
- data/docs/api/Brut/CLI/Apps/DeployBase.html +1 -1
- data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +1 -1
- data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +1 -1
- data/docs/api/Brut/CLI/Apps/Scaffold.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/Audit.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/E2e.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/JS.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test/Run.html +1 -1
- data/docs/api/Brut/CLI/Apps/Test.html +1 -1
- data/docs/api/Brut/CLI/Apps.html +1 -1
- data/docs/api/Brut/CLI/Command.html +1 -1
- data/docs/api/Brut/CLI/Error.html +1 -1
- data/docs/api/Brut/CLI/ExecutionResults/Result.html +1 -1
- data/docs/api/Brut/CLI/ExecutionResults.html +1 -1
- data/docs/api/Brut/CLI/Executor.html +1 -1
- data/docs/api/Brut/CLI/InvalidOption.html +1 -1
- data/docs/api/Brut/CLI/Options.html +1 -1
- data/docs/api/Brut/CLI/Output.html +1 -1
- data/docs/api/Brut/CLI/SystemExecError.html +1 -1
- data/docs/api/Brut/CLI.html +1 -1
- data/docs/api/Brut/FactoryBot.html +1 -1
- data/docs/api/Brut/Framework/App.html +1 -1
- data/docs/api/Brut/Framework/Config.html +11 -21
- data/docs/api/Brut/Framework/Container.html +1 -1
- data/docs/api/Brut/Framework/Error.html +1 -1
- data/docs/api/Brut/Framework/Errors/AbstractMethod.html +1 -1
- data/docs/api/Brut/Framework/Errors/Bug.html +1 -1
- data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +1 -1
- data/docs/api/Brut/Framework/Errors/MissingParameter.html +1 -1
- data/docs/api/Brut/Framework/Errors/NoClassForPath.html +1 -1
- data/docs/api/Brut/Framework/Errors/NotFound.html +1 -1
- data/docs/api/Brut/Framework/Errors/NotImplemented.html +1 -1
- data/docs/api/Brut/Framework/Errors.html +1 -1
- data/docs/api/Brut/Framework/FussyTypeEnforcement.html +1 -1
- data/docs/api/Brut/Framework/MCP.html +1 -1
- data/docs/api/Brut/Framework/ProjectEnvironment.html +1 -1
- data/docs/api/Brut/Framework.html +1 -1
- data/docs/api/Brut/FrontEnd/AssetPathResolver.html +1 -1
- data/docs/api/Brut/FrontEnd/Component/Helpers.html +1 -1
- data/docs/api/Brut/FrontEnd/Component.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/FormTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Input.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Inputs.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/TimeTag.html +1 -1
- data/docs/api/Brut/FrontEnd/Components/Traceparent.html +1 -1
- data/docs/api/Brut/FrontEnd/Components.html +1 -1
- data/docs/api/Brut/FrontEnd/CsrfProtector.html +1 -1
- data/docs/api/Brut/FrontEnd/Download.html +1 -1
- data/docs/api/Brut/FrontEnd/Flash.html +1 -1
- data/docs/api/Brut/FrontEnd/Form.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/Input.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +1 -1
- data/docs/api/Brut/FrontEnd/Forms.html +1 -1
- data/docs/api/Brut/FrontEnd/GenericResponse.html +1 -1
- data/docs/api/Brut/FrontEnd/Handler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Handlers.html +1 -1
- data/docs/api/Brut/FrontEnd/HandlingResults.html +1 -1
- data/docs/api/Brut/FrontEnd/HttpMethod.html +1 -1
- data/docs/api/Brut/FrontEnd/HttpStatus.html +1 -1
- data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +1 -1
- data/docs/api/Brut/FrontEnd/Layout.html +1 -1
- data/docs/api/Brut/FrontEnd/Middleware.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +1 -1
- data/docs/api/Brut/FrontEnd/Middlewares.html +1 -1
- data/docs/api/Brut/FrontEnd/Page.html +1 -1
- data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +1 -1
- data/docs/api/Brut/FrontEnd/Pages.html +1 -1
- data/docs/api/Brut/FrontEnd/RequestContext.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHook.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +1 -1
- data/docs/api/Brut/FrontEnd/RouteHooks.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing/Route.html +1 -1
- data/docs/api/Brut/FrontEnd/Routing.html +1 -1
- data/docs/api/Brut/FrontEnd/Session.html +1 -1
- data/docs/api/Brut/FrontEnd.html +1 -1
- data/docs/api/Brut/I18n/BaseMethods.html +1 -1
- data/docs/api/Brut/I18n/ForBackEnd.html +1 -1
- data/docs/api/Brut/I18n/ForCLI.html +1 -1
- data/docs/api/Brut/I18n/ForHTML.html +1 -1
- data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +1 -1
- data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +1 -1
- data/docs/api/Brut/I18n.html +1 -1
- data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +1 -1
- data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +1 -1
- data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +1 -1
- data/docs/api/Brut/Instrumentation/OpenTelemetry.html +1 -1
- data/docs/api/Brut/Instrumentation.html +1 -1
- data/docs/api/Brut/RubocopConfig.html +1 -1
- data/docs/api/Brut/SinatraHelpers/ClassMethods.html +1 -1
- data/docs/api/Brut/SinatraHelpers.html +1 -1
- data/docs/api/Brut/SpecSupport/ClockSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/ComponentSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/E2ETestServer.html +1 -1
- data/docs/api/Brut/SpecSupport/E2eSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/EnhancedNode.html +1 -1
- data/docs/api/Brut/SpecSupport/FlashSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +1 -1
- data/docs/api/Brut/SpecSupport/GeneralSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/HandlerSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +1 -1
- data/docs/api/Brut/SpecSupport/Matchers.html +1 -1
- data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +1 -1
- data/docs/api/Brut/SpecSupport/RSpecSetup.html +1 -1
- data/docs/api/Brut/SpecSupport/SessionSupport.html +1 -1
- data/docs/api/Brut/SpecSupport.html +1 -1
- data/docs/api/Brut.html +1 -1
- data/docs/api/Clock.html +1 -1
- data/docs/api/ModuleName.html +1 -1
- data/docs/api/RichString.html +1 -1
- data/docs/api/SemanticLogger/Appender/Async.html +1 -1
- data/docs/api/Sequel/Extensions/BrutInstrumentation.html +1 -1
- data/docs/api/Sequel/Extensions/BrutMigrations.html +1 -1
- data/docs/api/Sequel/Extensions.html +1 -1
- data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +1 -1
- data/docs/api/Sequel/Plugins/CreatedAt.html +1 -1
- data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +1 -1
- data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +1 -1
- data/docs/api/Sequel/Plugins/ExternalId.html +1 -1
- data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +1 -1
- data/docs/api/Sequel/Plugins/FindBang.html +1 -1
- data/docs/api/Sequel/Plugins.html +1 -1
- data/docs/api/Sequel.html +1 -1
- data/docs/api/_index.html +1 -1
- data/docs/api/file.README.html +1 -1
- data/docs/api/index.html +1 -1
- data/docs/api/top-level-namespace.html +1 -1
- data/docs/assets/{app.CmkhEsw7.js → app.BuBdZoUg.js} +1 -1
- data/docs/assets/basic-form-with-violations.Cv6Y9-Q_.png +0 -0
- data/docs/assets/basic-form.DbHnu0oW.png +0 -0
- data/docs/assets/chunks/@localSearchIndexroot.BZ_a3X0T.js +1 -0
- data/docs/assets/chunks/{VPLocalSearchBox.CDh583Oj.js → VPLocalSearchBox.UtnyvkX-.js} +1 -1
- data/docs/assets/chunks/{theme.B0_7GeW8.js → theme.DqwvuBEK.js} +2 -2
- data/docs/assets/{components.md.-22ecBxM.js → components.md.Bu80E2Nr.js} +3 -3
- data/docs/assets/{configuration.md.CLKL1lFf.js → configuration.md.CuIxVsSf.js} +1 -1
- data/docs/assets/{forms.md.CBI5--o2.js → forms.md.DnLbzVDa.js} +1 -1
- data/docs/assets/{getting-started.md.D5nzBZ4J.js → getting-started.md.DdQLmU3C.js} +2 -2
- data/docs/assets/initial-home-page.DNIaYmgP.png +0 -0
- data/docs/assets/new-post-editor.DrHr-5oh.png +0 -0
- data/docs/assets/new-post-home-page.Bm34lyMg.png +0 -0
- data/docs/assets/styled-form-with-server-side-violations.Bjxd8Dpv.png +0 -0
- data/docs/assets/styled-form-with-violations.Bv_sa9tg.png +0 -0
- data/docs/assets/styled-home-page-with-posts.Dd4kG89D.png +0 -0
- data/docs/assets/styled-home-page.BzdI7dWz.png +0 -0
- data/docs/assets/tutorial.md.C4zR5XPG.js +728 -0
- data/docs/assets/tutorial.md.C4zR5XPG.lean.js +1 -0
- data/docs/assets/welcome-to-brut.VSWzl17-.png +0 -0
- data/docs/assets.html +3 -3
- data/docs/brut-js/api/AjaxSubmit.html +1 -1
- data/docs/brut-js/api/AjaxSubmit.js.html +1 -1
- data/docs/brut-js/api/Autosubmit.html +1 -1
- data/docs/brut-js/api/Autosubmit.js.html +1 -1
- data/docs/brut-js/api/BaseCustomElement.html +1 -1
- data/docs/brut-js/api/BaseCustomElement.js.html +1 -1
- data/docs/brut-js/api/BrutCustomElements.html +1 -1
- data/docs/brut-js/api/BufferedLogger.html +1 -1
- data/docs/brut-js/api/ConfirmSubmit.html +18 -10
- data/docs/brut-js/api/ConfirmSubmit.js.html +29 -8
- data/docs/brut-js/api/ConfirmationDialog.html +1 -1
- data/docs/brut-js/api/ConfirmationDialog.js.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessage.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessage.js.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessages.html +1 -1
- data/docs/brut-js/api/ConstraintViolationMessages.js.html +1 -1
- data/docs/brut-js/api/CopyToClipboard.html +1 -1
- data/docs/brut-js/api/CopyToClipboard.js.html +1 -1
- data/docs/brut-js/api/Form.html +1 -1
- data/docs/brut-js/api/Form.js.html +1 -1
- data/docs/brut-js/api/I18nTranslation.html +1 -1
- data/docs/brut-js/api/I18nTranslation.js.html +1 -1
- data/docs/brut-js/api/LocaleDetection.html +1 -1
- data/docs/brut-js/api/LocaleDetection.js.html +1 -1
- data/docs/brut-js/api/Logger.html +1 -1
- data/docs/brut-js/api/Logger.js.html +1 -1
- data/docs/brut-js/api/Message.html +1 -1
- data/docs/brut-js/api/Message.js.html +1 -1
- data/docs/brut-js/api/PrefixedLogger.html +1 -1
- data/docs/brut-js/api/RichString.html +1 -1
- data/docs/brut-js/api/RichString.js.html +1 -1
- data/docs/brut-js/api/Tabs.html +1 -1
- data/docs/brut-js/api/Tabs.js.html +1 -1
- data/docs/brut-js/api/Tracing.html +1 -1
- data/docs/brut-js/api/Tracing.js.html +1 -1
- data/docs/brut-js/api/external-CustomElementRegistry.html +1 -1
- data/docs/brut-js/api/external-Performance.html +1 -1
- data/docs/brut-js/api/external-Promise.html +1 -1
- data/docs/brut-js/api/external-ValidityState.html +1 -1
- data/docs/brut-js/api/external-Window.html +1 -1
- data/docs/brut-js/api/external-fetch.html +1 -1
- data/docs/brut-js/api/global.html +1 -1
- data/docs/brut-js/api/index.html +1 -1
- data/docs/brut-js/api/index.js.html +1 -1
- data/docs/brut-js/api/module-testing.html +1 -1
- data/docs/brut-js/api/testing.AssetMetadata.html +1 -1
- data/docs/brut-js/api/testing.AssetMetadataLoader.html +1 -1
- data/docs/brut-js/api/testing.CustomElementTest.html +1 -1
- data/docs/brut-js/api/testing.DOMCreator.html +1 -1
- data/docs/brut-js/api/testing_AssetMetadata.js.html +1 -1
- data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +1 -1
- data/docs/brut-js/api/testing_CustomElementTest.js.html +1 -1
- data/docs/brut-js/api/testing_DOMCreator.js.html +1 -1
- data/docs/brut-js/api/testing_index.js.html +1 -1
- data/docs/brut-js.html +3 -3
- data/docs/business-logic.html +3 -3
- data/docs/cli.html +3 -3
- data/docs/components.html +7 -7
- data/docs/configuration.html +5 -5
- data/docs/css.html +3 -3
- data/docs/custom-element-tests.html +3 -3
- data/docs/database-access.html +3 -3
- data/docs/database-schema.html +3 -3
- data/docs/deployment.html +3 -3
- data/docs/dev-environment.html +3 -3
- data/docs/dir-structure.html +3 -3
- data/docs/doc-conventions.html +3 -3
- data/docs/end-to-end-tests.html +3 -3
- data/docs/features.html +3 -3
- data/docs/flash-and-session.html +3 -3
- data/docs/form-constraints.html +3 -3
- data/docs/forms.html +5 -5
- data/docs/getting-started.html +6 -6
- data/docs/handlers.html +3 -3
- data/docs/hashmap.json +1 -1
- data/docs/hooks.html +3 -3
- data/docs/i18n.html +3 -3
- data/docs/index.html +3 -3
- data/docs/instrumentation.html +3 -3
- data/docs/javascript.html +3 -3
- data/docs/jobs.html +3 -3
- data/docs/keyword-injection.html +3 -3
- data/docs/layouts.html +3 -3
- data/docs/lsp.html +3 -3
- data/docs/markdown-examples.html +3 -3
- data/docs/middleware.html +3 -3
- data/docs/overview.html +3 -3
- data/docs/pages.html +3 -3
- data/docs/recipes/alternate-layouts.html +3 -3
- data/docs/recipes/authentication.html +3 -3
- data/docs/recipes/blank-layouts.html +3 -3
- data/docs/recipes/custom-flash.html +3 -3
- data/docs/recipes/indexed-forms.html +3 -3
- data/docs/recipes/migrations.html +3 -3
- data/docs/recipes/text-field-component.html +3 -3
- data/docs/roadmap.html +3 -3
- data/docs/routes.html +3 -3
- data/docs/security.html +3 -3
- data/docs/seed-data.html +3 -3
- data/docs/space-time-continuum.html +3 -3
- data/docs/tutorial.html +732 -5
- data/docs/unit-tests.html +3 -3
- data/docs/why.html +3 -3
- data/lib/brut/framework/config.rb +9 -14
- data/lib/brut/version.rb +1 -1
- data/mkbrut/Gemfile.lock +1 -1
- data/mkbrut/lib/mkbrut/version.rb +1 -1
- metadata +35 -15
- data/docs/assets/chunks/@localSearchIndexroot.DUha-mf5.js +0 -1
- data/docs/assets/tutorial.md.BIb7XT6j.js +0 -1
- data/docs/assets/tutorial.md.BIb7XT6j.lean.js +0 -1
- /data/docs/assets/{components.md.-22ecBxM.lean.js → components.md.Bu80E2Nr.lean.js} +0 -0
- /data/docs/assets/{configuration.md.CLKL1lFf.lean.js → configuration.md.CuIxVsSf.lean.js} +0 -0
- /data/docs/assets/{forms.md.CBI5--o2.lean.js → forms.md.DnLbzVDa.lean.js} +0 -0
- /data/docs/assets/{getting-started.md.D5nzBZ4J.lean.js → getting-started.md.DdQLmU3C.lean.js} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b580e8b69cc722fb2d84c090f7848b9c45623de2faaa996a14914d52773c48a
|
4
|
+
data.tar.gz: 37b84eb37ac974c48c054be0305086622fab712345d7ef581b7bd58f3ec7a79e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43f5d19e8bb88c0e0956757b1826224f18f68eed46ef34d5a7e8df73b7a8638fb674f499c5e335edae84bd42fb2266fbb19ec347c7e14cbb18027c832e66f33b
|
7
|
+
data.tar.gz: 7b12806b7ce2164e6d1dd2eb85dc3d01902113fadb6762babcd265d8cca3659dc3bf2913db160c518c6ade57624d2e4558d779a62151807a6c0a9f7e4f2c72e9
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Brut CHANGELOG
|
2
2
|
|
3
|
+
## v0.9.1 - Aug 12, 2025
|
4
|
+
|
5
|
+
* Changed `<brut-confirm-submit>` to not ask for confirmation if the form is invalid
|
6
|
+
* Changed default production loggin to STDOUT as this is more correct + it cannot be changed by apps
|
7
|
+
currently due to https://github.com/thirdtank/brut/issues/51
|
8
|
+
|
3
9
|
## v0.9.0 - Aug 7, 2025
|
4
10
|
|
5
11
|
* Added `Brut::FrontEnd::CsrfProtector` and the `csrf_protector` configuration option to allow some customization
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
brut (0.9.
|
4
|
+
brut (0.9.1)
|
5
5
|
concurrent-ruby
|
6
6
|
i18n
|
7
7
|
irb
|
@@ -23,7 +23,7 @@ PATH
|
|
23
23
|
GEM
|
24
24
|
remote: https://rubygems.org/
|
25
25
|
specs:
|
26
|
-
activesupport (8.0.
|
26
|
+
activesupport (8.0.2)
|
27
27
|
base64
|
28
28
|
benchmark (>= 0.3)
|
29
29
|
bigdecimal
|
@@ -37,131 +37,135 @@ GEM
|
|
37
37
|
tzinfo (~> 2.0, >= 2.0.5)
|
38
38
|
uri (>= 0.13.1)
|
39
39
|
ast (2.4.3)
|
40
|
-
base64 (0.
|
41
|
-
benchmark (0.4.
|
42
|
-
bigdecimal (3.
|
43
|
-
concurrent-ruby (1.3.
|
44
|
-
connection_pool (2.
|
40
|
+
base64 (0.3.0)
|
41
|
+
benchmark (0.4.1)
|
42
|
+
bigdecimal (3.2.2)
|
43
|
+
concurrent-ruby (1.3.5)
|
44
|
+
connection_pool (2.5.3)
|
45
45
|
date (3.4.1)
|
46
|
-
diff-lcs (1.
|
47
|
-
dotenv (3.1.
|
48
|
-
drb (2.2.
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
diff-lcs (1.6.2)
|
47
|
+
dotenv (3.1.8)
|
48
|
+
drb (2.2.3)
|
49
|
+
erb (5.0.2)
|
50
|
+
factory_bot (6.5.4)
|
51
|
+
activesupport (>= 6.1.0)
|
52
|
+
faker (3.5.2)
|
52
53
|
i18n (>= 1.8.11, < 2)
|
53
|
-
google-protobuf (4.
|
54
|
+
google-protobuf (4.31.1)
|
54
55
|
bigdecimal
|
55
56
|
rake (>= 13)
|
56
|
-
google-protobuf (4.
|
57
|
+
google-protobuf (4.31.1-aarch64-linux-gnu)
|
57
58
|
bigdecimal
|
58
59
|
rake (>= 13)
|
59
|
-
google-protobuf (4.
|
60
|
+
google-protobuf (4.31.1-arm64-darwin)
|
60
61
|
bigdecimal
|
61
62
|
rake (>= 13)
|
62
|
-
google-protobuf (4.
|
63
|
+
google-protobuf (4.31.1-x86-linux-gnu)
|
63
64
|
bigdecimal
|
64
65
|
rake (>= 13)
|
65
|
-
google-protobuf (4.
|
66
|
+
google-protobuf (4.31.1-x86_64-darwin)
|
66
67
|
bigdecimal
|
67
68
|
rake (>= 13)
|
68
|
-
google-protobuf (4.
|
69
|
+
google-protobuf (4.31.1-x86_64-linux-gnu)
|
69
70
|
bigdecimal
|
70
71
|
rake (>= 13)
|
71
|
-
googleapis-common-protos-types (1.
|
72
|
+
googleapis-common-protos-types (1.20.0)
|
72
73
|
google-protobuf (>= 3.18, < 5.a)
|
73
|
-
i18n (1.14.
|
74
|
+
i18n (1.14.7)
|
74
75
|
concurrent-ruby (~> 1.0)
|
75
|
-
io-console (0.8.
|
76
|
-
irb (1.15.
|
76
|
+
io-console (0.8.1)
|
77
|
+
irb (1.15.2)
|
77
78
|
pp (>= 0.6.0)
|
78
79
|
rdoc (>= 4.0.0)
|
79
80
|
reline (>= 0.4.2)
|
80
|
-
json (2.13.
|
81
|
+
json (2.13.2)
|
81
82
|
language_server-protocol (3.17.0.5)
|
82
83
|
lint_roller (1.1.0)
|
83
|
-
logger (1.
|
84
|
+
logger (1.7.0)
|
84
85
|
mini_portile2 (2.8.9)
|
85
|
-
minitest (5.25.
|
86
|
-
mustermann (3.0.
|
86
|
+
minitest (5.25.5)
|
87
|
+
mustermann (3.0.4)
|
87
88
|
ruby2_keywords (~> 0.0.1)
|
88
|
-
nokogiri (1.18.
|
89
|
+
nokogiri (1.18.9)
|
89
90
|
mini_portile2 (~> 2.8.2)
|
90
91
|
racc (~> 1.4)
|
91
|
-
nokogiri (1.18.
|
92
|
+
nokogiri (1.18.9-aarch64-linux-gnu)
|
92
93
|
racc (~> 1.4)
|
93
|
-
nokogiri (1.18.
|
94
|
+
nokogiri (1.18.9-arm-linux-gnu)
|
94
95
|
racc (~> 1.4)
|
95
|
-
nokogiri (1.18.
|
96
|
+
nokogiri (1.18.9-arm64-darwin)
|
96
97
|
racc (~> 1.4)
|
97
|
-
nokogiri (1.18.
|
98
|
+
nokogiri (1.18.9-x86_64-darwin)
|
98
99
|
racc (~> 1.4)
|
99
|
-
nokogiri (1.18.
|
100
|
+
nokogiri (1.18.9-x86_64-linux-gnu)
|
100
101
|
racc (~> 1.4)
|
101
|
-
opentelemetry-api (1.
|
102
|
-
opentelemetry-common (0.
|
102
|
+
opentelemetry-api (1.5.0)
|
103
|
+
opentelemetry-common (0.22.0)
|
103
104
|
opentelemetry-api (~> 1.0)
|
104
|
-
opentelemetry-exporter-otlp (0.
|
105
|
+
opentelemetry-exporter-otlp (0.30.0)
|
105
106
|
google-protobuf (>= 3.18)
|
106
107
|
googleapis-common-protos-types (~> 1.3)
|
107
108
|
opentelemetry-api (~> 1.1)
|
108
109
|
opentelemetry-common (~> 0.20)
|
109
110
|
opentelemetry-sdk (~> 1.2)
|
110
111
|
opentelemetry-semantic_conventions
|
111
|
-
opentelemetry-registry (0.
|
112
|
+
opentelemetry-registry (0.4.0)
|
112
113
|
opentelemetry-api (~> 1.1)
|
113
|
-
opentelemetry-sdk (1.
|
114
|
+
opentelemetry-sdk (1.8.0)
|
114
115
|
opentelemetry-api (~> 1.1)
|
115
116
|
opentelemetry-common (~> 0.20)
|
116
117
|
opentelemetry-registry (~> 0.2)
|
117
118
|
opentelemetry-semantic_conventions
|
118
|
-
opentelemetry-semantic_conventions (1.
|
119
|
+
opentelemetry-semantic_conventions (1.11.0)
|
119
120
|
opentelemetry-api (~> 1.0)
|
120
|
-
ostruct (0.6.
|
121
|
+
ostruct (0.6.3)
|
121
122
|
parallel (1.27.0)
|
122
|
-
parser (3.3.
|
123
|
+
parser (3.3.9.0)
|
123
124
|
ast (~> 2.4.1)
|
124
125
|
racc
|
125
|
-
phlex (2.
|
126
|
+
phlex (2.3.1)
|
126
127
|
zeitwerk (~> 2.7)
|
127
128
|
pp (0.6.2)
|
128
129
|
prettyprint
|
129
130
|
prettyprint (0.2.0)
|
130
|
-
prism (1.
|
131
|
-
psych (5.2.
|
131
|
+
prism (1.4.0)
|
132
|
+
psych (5.2.6)
|
132
133
|
date
|
133
134
|
stringio
|
134
135
|
racc (1.8.1)
|
135
|
-
rack (3.
|
136
|
-
rack-protection (4.
|
136
|
+
rack (3.2.0)
|
137
|
+
rack-protection (4.1.1)
|
137
138
|
base64 (>= 0.1.0)
|
139
|
+
logger (>= 1.6.0)
|
138
140
|
rack (>= 3.0.0, < 4)
|
139
|
-
rack-session (2.
|
141
|
+
rack-session (2.1.1)
|
142
|
+
base64 (>= 0.1.0)
|
140
143
|
rack (>= 3.0.0)
|
141
144
|
rackup (2.2.1)
|
142
145
|
rack (>= 3)
|
143
146
|
rainbow (3.1.1)
|
144
|
-
rake (13.
|
147
|
+
rake (13.3.0)
|
145
148
|
rdiscount (2.2.7.3)
|
146
|
-
rdoc (6.
|
149
|
+
rdoc (6.14.2)
|
150
|
+
erb
|
147
151
|
psych (>= 4.0.0)
|
148
|
-
regexp_parser (2.
|
149
|
-
reline (0.6.
|
152
|
+
regexp_parser (2.11.1)
|
153
|
+
reline (0.6.2)
|
150
154
|
io-console (~> 0.5)
|
151
|
-
rspec (3.13.
|
155
|
+
rspec (3.13.1)
|
152
156
|
rspec-core (~> 3.13.0)
|
153
157
|
rspec-expectations (~> 3.13.0)
|
154
158
|
rspec-mocks (~> 3.13.0)
|
155
|
-
rspec-core (3.13.
|
159
|
+
rspec-core (3.13.5)
|
156
160
|
rspec-support (~> 3.13.0)
|
157
|
-
rspec-expectations (3.13.
|
161
|
+
rspec-expectations (3.13.5)
|
158
162
|
diff-lcs (>= 1.2.0, < 2.0)
|
159
163
|
rspec-support (~> 3.13.0)
|
160
|
-
rspec-mocks (3.13.
|
164
|
+
rspec-mocks (3.13.5)
|
161
165
|
diff-lcs (>= 1.2.0, < 2.0)
|
162
166
|
rspec-support (~> 3.13.0)
|
163
|
-
rspec-support (3.13.
|
164
|
-
rubocop (1.
|
167
|
+
rspec-support (3.13.4)
|
168
|
+
rubocop (1.79.2)
|
165
169
|
json (~> 2.3)
|
166
170
|
language_server-protocol (~> 3.17.0.2)
|
167
171
|
lint_roller (~> 1.1.0)
|
@@ -169,39 +173,41 @@ GEM
|
|
169
173
|
parser (>= 3.3.0.2)
|
170
174
|
rainbow (>= 2.2.2, < 4.0)
|
171
175
|
regexp_parser (>= 2.9.3, < 3.0)
|
172
|
-
rubocop-ast (>= 1.
|
176
|
+
rubocop-ast (>= 1.46.0, < 2.0)
|
173
177
|
ruby-progressbar (~> 1.7)
|
174
178
|
unicode-display_width (>= 2.4.0, < 4.0)
|
175
|
-
rubocop-ast (1.
|
179
|
+
rubocop-ast (1.46.0)
|
176
180
|
parser (>= 3.3.7.2)
|
181
|
+
prism (~> 1.4)
|
177
182
|
rubocop-disable_syntax (0.2.0)
|
178
183
|
lint_roller
|
179
184
|
rubocop (>= 1.72.0)
|
180
185
|
ruby-progressbar (1.13.0)
|
181
186
|
ruby2_keywords (0.0.5)
|
182
|
-
securerandom (0.
|
183
|
-
semantic_logger (4.
|
187
|
+
securerandom (0.4.1)
|
188
|
+
semantic_logger (4.17.0)
|
184
189
|
concurrent-ruby (~> 1.0)
|
185
|
-
sequel (5.
|
190
|
+
sequel (5.95.1)
|
186
191
|
bigdecimal
|
187
|
-
sinatra (4.
|
192
|
+
sinatra (4.1.1)
|
193
|
+
logger (>= 1.6.0)
|
188
194
|
mustermann (~> 3.0)
|
189
195
|
rack (>= 3.0.0, < 4)
|
190
|
-
rack-protection (= 4.
|
196
|
+
rack-protection (= 4.1.1)
|
191
197
|
rack-session (>= 2.0.0, < 3)
|
192
198
|
tilt (~> 2.0)
|
193
|
-
stringio (3.1.
|
194
|
-
tilt (2.
|
199
|
+
stringio (3.1.7)
|
200
|
+
tilt (2.6.1)
|
195
201
|
tzinfo (2.0.6)
|
196
202
|
concurrent-ruby (~> 1.0)
|
197
|
-
tzinfo-data (1.
|
203
|
+
tzinfo-data (1.2025.2)
|
198
204
|
tzinfo (>= 1.0.0)
|
199
205
|
unicode-display_width (3.1.4)
|
200
206
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
201
207
|
unicode-emoji (4.0.4)
|
202
|
-
uri (1.0.
|
208
|
+
uri (1.0.3)
|
203
209
|
yard (0.9.37)
|
204
|
-
zeitwerk (2.7.
|
210
|
+
zeitwerk (2.7.3)
|
205
211
|
|
206
212
|
PLATFORMS
|
207
213
|
aarch64-linux
|
data/brut-css/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "brut-css",
|
3
|
-
"version": "0.9.
|
3
|
+
"version": "0.9.1",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "brut-css",
|
9
|
-
"version": "0.9.
|
9
|
+
"version": "0.9.1",
|
10
10
|
"license": "Hippocratic-2.1",
|
11
11
|
"devDependencies": {
|
12
12
|
"comment-parser": "^1.4.1",
|
data/brut-css/package.json
CHANGED
data/brut-js/package-lock.json
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "brut-js",
|
3
|
-
"version": "0.9.
|
3
|
+
"version": "0.9.1",
|
4
4
|
"lockfileVersion": 3,
|
5
5
|
"requires": true,
|
6
6
|
"packages": {
|
7
7
|
"": {
|
8
8
|
"name": "brut-js",
|
9
|
-
"version": "0.9.
|
9
|
+
"version": "0.9.1",
|
10
10
|
"license": "Hippocratic-2.1",
|
11
11
|
"devDependencies": {
|
12
12
|
"esbuild": "^0.24.0",
|
data/brut-js/package.json
CHANGED
@@ -7,7 +7,7 @@ describe("<brut-confirm-submit>", () => {
|
|
7
7
|
<input type="text" name="text">
|
8
8
|
<brut-confirm-submit message='You sure?'>
|
9
9
|
<button>Save</button>
|
10
|
-
<input type="submit" value="Submit">
|
10
|
+
<input type="submit" value="Submit" required minlength="3" value="abcd">
|
11
11
|
</brut-confirm-submit>
|
12
12
|
</form>
|
13
13
|
`).test("uses window.confirm and cancels the click on Cancel", ({window,document,assert}) => {
|
@@ -82,6 +82,37 @@ describe("<brut-confirm-submit>", () => {
|
|
82
82
|
assert.equal(messageShown,"You sure?")
|
83
83
|
assert(submitted)
|
84
84
|
})
|
85
|
+
withHTML(`
|
86
|
+
<form>
|
87
|
+
<input type="text" name="text" required minlength="3">
|
88
|
+
<brut-confirm-submit message='You sure?'>
|
89
|
+
<button>Save</button>
|
90
|
+
<input type="submit" value="Submit">
|
91
|
+
</brut-confirm-submit>
|
92
|
+
</form>
|
93
|
+
`).test("Does not show if form is invalid", ({window,document,assert}) => {
|
94
|
+
const form = document.querySelector("form")
|
95
|
+
const button = document.querySelector("button")
|
96
|
+
|
97
|
+
let submitted = false
|
98
|
+
form.addEventListener("submit", (event) => {
|
99
|
+
event.preventDefault()
|
100
|
+
submitted = true
|
101
|
+
})
|
102
|
+
|
103
|
+
let shown = false
|
104
|
+
let messageShown = null
|
105
|
+
|
106
|
+
window.confirm = (message) => {
|
107
|
+
shown = true
|
108
|
+
messageShown = message
|
109
|
+
return false // "Cancel"
|
110
|
+
}
|
111
|
+
|
112
|
+
button.click()
|
113
|
+
assert(!shown)
|
114
|
+
assert(!submitted)
|
115
|
+
})
|
85
116
|
})
|
86
117
|
describe("with an implicit dialog", () => {
|
87
118
|
withHTML(`
|
@@ -2,14 +2,21 @@ import BaseCustomElement from "./BaseCustomElement"
|
|
2
2
|
import RichString from "./RichString"
|
3
3
|
import ConfirmationDialog from "./ConfirmationDialog"
|
4
4
|
|
5
|
-
/** Confirms form submissions with the user before allowing the form to be submitted. This
|
6
|
-
*
|
7
|
-
* has been put onto those buttons. Note that this does not affect links (`a` elements).
|
5
|
+
/** Confirms form submissions with the user before allowing the form to be submitted. This is applied
|
6
|
+
* to buttons, not forms, to allow for finer control over the behavior.
|
8
7
|
*
|
9
|
-
* This
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
8
|
+
* * This only works for `button` or `input type=submit`
|
9
|
+
* * The elements must have a form, either by being inside a form or having
|
10
|
+
* a `form` attribute.
|
11
|
+
* * If the form is not valid, it will not show the confirmation dialog.
|
12
|
+
*
|
13
|
+
*
|
14
|
+
* By default, this will use {@link external:Window#confirm}. if "OK" is pressed,
|
15
|
+
* the button click goes through and the form would be submitted. If "Cancel" is pressed,
|
16
|
+
* the event is prevented.
|
17
|
+
*
|
18
|
+
* If there is a `brut-confirmation-dialog` on the page, this component can use that, possibly
|
19
|
+
* with help from the `dialog` attribute as followed:
|
13
20
|
*
|
14
21
|
* * If `dialog` is set:
|
15
22
|
* - If that id is on a `<brut-confirmation-dialog>` that is used.
|
@@ -18,6 +25,9 @@ import ConfirmationDialog from "./ConfirmationDialog"
|
|
18
25
|
* - If there is exactly one `<brut-confirmation-dialog>` on the page, this is used.
|
19
26
|
* - If there is more than one, or no `<brut-confirmation-dialog>`s, `window.confirm` is used.
|
20
27
|
*
|
28
|
+
* If the wrong dialog or notification method is happening, set `show-warnings` on the element, and it will
|
29
|
+
* print out why it's doing what it's doing.
|
30
|
+
*
|
21
31
|
* @see ConfirmationDialog
|
22
32
|
*
|
23
33
|
* @property {string} message - the message to show that asks for confirmation. It should be written such that
|
@@ -60,6 +70,17 @@ class ConfirmSubmit extends BaseCustomElement {
|
|
60
70
|
this.logger.warn("No message provided, so cannot confirm")
|
61
71
|
return
|
62
72
|
}
|
73
|
+
const form = event.currentTarget.form
|
74
|
+
|
75
|
+
if (!form) {
|
76
|
+
this.logger.warn("Element was not part of a form, so cannot confirm submission")
|
77
|
+
return
|
78
|
+
}
|
79
|
+
|
80
|
+
if (!form.checkValidity()) {
|
81
|
+
return
|
82
|
+
}
|
83
|
+
|
63
84
|
const dialog = this.#findDialog()
|
64
85
|
if (dialog) {
|
65
86
|
event.preventDefault()
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|