diff --git a/applications/rest-service/commands.txt b/applications/rest-service/commands.txt deleted file mode 100644 index c001033f1..000000000 --- a/applications/rest-service/commands.txt +++ /dev/null @@ -1,2 +0,0 @@ -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED -jar spring-boot-upgrade.jar /Users/fkrueger/projects/sbm-projects/demo-spring-song-app -java --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED -jar spring-boot-upgrade.jar /Users/fkrueger/projects/sbm-projects/demo-spring-song-app \ No newline at end of file diff --git a/applications/rest-service/src/main/java/org/springframework/sbm/SpringBootMigratorServiceApp.java b/applications/rest-service/src/main/java/org/springframework/sbm/SpringBootMigratorServiceApp.java deleted file mode 100644 index 2747e39e5..000000000 --- a/applications/rest-service/src/main/java/org/springframework/sbm/SpringBootMigratorServiceApp.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2021 - 2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.sbm; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.ApplicationRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; -import org.springframework.http.MediaType; -import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportFileSystemRenderer; -import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportRenderer; -import org.springframework.sbm.engine.commands.ApplyCommand; -import org.springframework.sbm.engine.commands.ScanCommand; -import org.springframework.sbm.engine.context.ProjectContext; -import org.springframework.sbm.engine.context.ProjectContextHolder; -import org.springframework.sbm.engine.events.*; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -@SpringBootApplication -public class SpringBootMigratorServiceApp implements ApplicationRunner { - - public static void main(String[] args) { - if(args.length == 0) { - System.err.println("PLease provide the path to the application as parameter."); - return; - } - SpringApplication.run(SpringBootMigratorServiceApp.class, args); - } - - @Autowired - private ScanCommand scanCommand; - @Autowired - private ApplyCommand applyCommand; - @Autowired - private SpringBootUpgradeReportRenderer upgradeReportRenderer; - @Autowired - private ProjectContextHolder contextHolder; - - @Autowired - private ReportHolder reportHolder; - - @Override - public void run(ApplicationArguments args) { - String applicationPath = args.getSourceArgs()[0]; - System.out.println("Scanning " + applicationPath); - ProjectContext context = scanCommand.execute(applicationPath); - contextHolder.setProjectContext(context); - System.out.println("finished scan. Please open: http://localhost:8080/spring-boot-upgrade"); - } - - -} - -@Controller -class ReportController{ - - @Autowired - private ApplyCommand applyCommand; - @Autowired - private ReportHolder reportHolder; - - @Autowired - private ProjectContextHolder contextHolder; - - @GetMapping(path = "/spring-boot-upgrade", produces = MediaType.TEXT_HTML_VALUE) - @ResponseBody - public String upgrade() { - applyCommand.execute(contextHolder.getProjectContext(), "boot-2.7-3.0-upgrade-report2"); - return reportHolder.getReport(); - } - - @PostMapping(path = "/spring-boot-upgrade", produces = MediaType.TEXT_HTML_VALUE) - @ResponseBody - public String applyRecipe(@RequestParam String recipeName) { - ProjectContext context = contextHolder.getProjectContext(); - applyCommand.execute(context, recipeName); - applyCommand.execute(context, "boot-2.7-3.0-upgrade-report2"); - return reportHolder.getReport(); - } -} diff --git a/applications/rest-service/src/main/resources/banner.txt b/applications/rest-service/src/main/resources/banner.txt deleted file mode 100644 index f007a9343..000000000 --- a/applications/rest-service/src/main/resources/banner.txt +++ /dev/null @@ -1,43 +0,0 @@ - - ,╓╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔╔µ, , - #╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╦ ]╬⌐ - @╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╦ ╔╣╚╣ - ║╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▒ ║╩ ╟▒ - ,╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣#╣└ ╣╕ - ╔╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╝└ ╙╣ - @╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣╙ ╫▒ - ╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╝╙ "╬ - ,╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣╩╙ ╫▒ - φ╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣╣╬╝╩╙╙└² ]╣ - Å╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣╩╙└└ ╬b - .╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣╩└ . ║▒ - ╒╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╩ ,⌐ ╚╬ - #╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╩ ╓╩ ]╬ - ║╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣ @╩ ]╬▒ - ║╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ φ╣╙ ]╬╬▒ - ╫╬╬╬╬╬╬╬╬╬╬╬╬╬╣ ╔╣╣` ║╬╬╬ - ╚╬╬╬╬╬╬╬╬╬╬╬╬╬▒ é╣╬╜ ╣╬╬╛ - ╙╬╬╬╬╬╬╬╬╬╬╬╬⌐ ╓▒╬╬╩ ]╬╬╙ - └╣╬╬╬╬╬╬╬╬╬╬⌐ »▒╣╬╬╩² ╣╣└ - ╬╬╬╬╬╬╬╬╬╬▒ ,╔▒╬╬╬╣╙ ╟╬ - ╚╬╬╬╬╬╬╬╬╬⌐ ╓#▒╣╬╬╬╬╩└ ╬╩ - ╙╬╬╬╬╬╬╬╬╣ε ²╓╗▒╬╣╬╬╬╬╬╣╨└ ╔╣╙ - "╣╬╬╬╬╬╬╬╬▒┐ ,╓╔╗@▒╣╬╬╬╬╬╬╬╬╬╣╨╙ ╔╬╣ - ╢╬╬╬╬╬╬╬╬╬╣▒▒╬╣╬╬╬╬╬╬╬╬╬╬╬╬╣╩╙└ ╓▒╣╬╬ - ╚╬╬╬╬╜ ╙╣╬╬╬╬╬╬╬╬╝╩╙└ ,╓φ▒╣╬╬╬╬╨ - ╙╣╬▒ .╬╬╬╬╬╠╗╗@@###@@╗╗╗╗╗╗╗╗╗╗╗╗╗╗#@▒▒╬╣╣╬╬╬╬╬╬╬╬╬┘ - ²╣╣╓ ,║╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣ - ║╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╩ - ╙╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╙ - └╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣└ - └╜╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╣╨└ - ²²²²²²²²²²²²²²²²²²²²²²²²²²²²²² - - - _______ _______ _______ _______ _______ _______ __ __ _______ _______ ______ _______ ______ _______ -| _ || || || | | | | _ | | | | || || || _ | | _ || | | | -| |_| || _ || _ ||_ _| |___ | | | | | | | | || _ || ___|| | || | |_| || _ || ___| -| || | | || | | | | | ___| | | | | | | |_| || |_| || | __ | |_||_ | || | | || |___ -| _ | | |_| || |_| | | | |___ | ___ | |_| | | || ___|| || || __ || || |_| || ___| -| |_| || || | | | ___| || | | | | || | | |_| || | | || _ || || |___ -|_______||_______||_______| |___| |_______||___| |_______| |_______||___| |_______||___| |_||__| |__||______| |_______| diff --git a/applications/rest-service/src/main/resources/static/css/site.css.map b/applications/rest-service/src/main/resources/static/css/site.css.map deleted file mode 100755 index e2e596d06..000000000 --- a/applications/rest-service/src/main/resources/static/css/site.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["settings.css","settings-dark.css","generic.css","elements.css","layout.css","asciidoctor.css","highlight.css","tabs.css","toc.css","codetools.css"],"names":[],"mappings":"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","file":"site.css","sourcesContent":["/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n:root {\n /* NOTE: Don't use relative `url()` values in here. Safari load them properly */\n\n /* General */\n --html-font-size: 1em;\n --pixel-to-rem: 16 * 1rem;\n --font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n \"Segoe UI Symbol\";\n --font-weight: 400;\n --monospace-font-family: \"SFMono-Regular\", \"Consolas\", \"Liberation Mono\",\n \"Menlo\", monospace;\n --body-background-color: white;\n --panel-background-color: #f6f8fa;\n --panel-group-background-color: #e1e8e8;\n --panel-border-color: #eaedf0;\n --color-accent-1: #ebf2f2;\n --color-accent-2: #d7e7e7;\n --color-accent-3: #6db33f;\n --body-font-color: #191e1e;\n --body-font-light-color: #273030;\n --body-font-dark-color: #141818;\n --link-font-color: #1565c0;\n --hover-link-font-color: #104d92;\n --scrollbar-thumb-color: silver;\n --mark-background-color: #39ff14;\n --selected-background-color: #191e1e;\n\n /* Layout */\n --layout-banner-logo-offset: 18px;\n --layout-banner-logo-height: 50px;\n --layout-max-width: 1400px;\n --layout-banner-height: 80px;\n --layout-border-color: var(--color-accent-1);\n --layout-switchtheme-invert-filter: invert();\n --layout-switchtheme-background-color: var(--body-background-color);\n --layout-switchtheme-button-color: var(--body-background-color);\n --layout-switchtheme-button-hover-color: var(--color-accent-1);\n\n /* Asciidoctor */\n --asciidoctor-doc-embellishment-margin-width: 250px;\n --asciidoctor-doc-background-embellishment-height: 147px;\n --asciidoctor-details-background: var(--color-accent-1);\n --asciidoctor-details-font-color: var(--body-font-light-color);\n --asciidoctor-author-separator-color: var(--color-accent-3);\n --asciidoctor-panel-background: var(--panel-background-color);\n --asciidoctor-panel-border-color: var(--panel-border-color);\n --asciidoctor-font-color: var(--body-font-color);\n --asciidoctor-heading-font-color: var(--body-font-dark-color);\n --asciidoctor-heading-font-weight: 600;\n --asciidoctor-alt-heading-font-weight: 600;\n --asciidoctor-section-divider-color: var(--color-accent-1);\n --asciidoctor-link-font-color: var(--link-font-color);\n --asciidoctor-hover-link-font-color: var(--hover-link-font-color);\n --asciidoctor-unresolved-link-font-color: #d32f2f;\n --asciidoctor-code-font-color: var(--asciidoctor-font-color);\n --asciidoctor-code-link-font-color: var(--link-font-color);\n --asciidoctor-code-background: rgba(27, 31, 35, 0.05);\n --asciidoctor-code-data-lang-color: #999;\n --asciidoctor-table-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-table-header-footer-background: var(--color-accent-1);\n --asciidoctor-table-stripe-background: var(--color-accent-1);\n --asciidoctor-table-footer-background: linear-gradient(\n to bottom,\n var(--color-accent-1) 0%,\n var(--body-background-color) 100%\n );\n --asciidoctor-admonition-background: var(--color-accent-1);\n --asciidoctor-admonition-pre-background: var(--color-accent-2);\n --asciidoctor-admonition-label-font-weight: 500;\n --asciidoctor-admonition-font-color: #f0f0f0;\n --asciidoctor-admonition-caution-background: #561164;\n --asciidoctor-admonition-important-background: #960000;\n --asciidoctor-admonition-note-background: #015785;\n --asciidoctor-admonition-tip-background: #3e6b1f;\n --asciidoctor-admonition-warning-background: #bd7400;\n --asciidoctor-abstract-background: var(--asciidoctor-panel-background);\n --asciidoctor-abstract-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-quote-background: var(--color-accent-1);\n --asciidoctor-quote-border-color: var(--color-accent-3);\n --asciidoctor-quote-attribution-font-color: var(--color-accent-3);\n --asciidoctor-caption-font-color: var(--body-font-light-color);\n --asciidoctor-caption-font-weight: 400;\n --asciidoctor-example-background: var(--asciidoctor-panel-background);\n --asciidoctor-example-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-sidebar-background: var(--color-accent-1);\n --asciidoctor-pre-background: var(--asciidoctor-panel-background);\n --asciidoctor-pre-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-callout-background: var(--body-font-dark-color);\n --asciidoctor-callout-font-color: var(--body-background-color);\n --asciidoctor-footer-font-color: #b6b6b6;\n\n /* Highlight JS (colors based on https://github.com/primer/github-syntax-light) */\n --highlight-background-color: var(--asciidoctor-pre-background);\n --highlight-font-color: #24292e;\n --highlight-keyword-font-color: #d73a49;\n --highlight-comment-font-color: #6a737d;\n --highlight-string-font-color: #032f62;\n --highlight-meta-font-color: #6a737d;\n --highlight-constant-font-color: #032f62;\n --highlight-variable-font-color: #005cc5;\n --highlight-tag-font-color: #22863a;\n --highlight-tag-attribute-font-color: #6f42c1;\n --highlight-type-font-color: #6f42c1;\n --highlight-link-font-color: var(--link-font-color);\n --highlight-addition-font-color: #22863a;\n --highlight-deletion-font-color: #24292e;\n --highlight-regex-font-color: #032f62;\n\n /* Tabs */\n --tabs-border-color: var(--selected-background-color);\n --tabs-background-color: var(--body-background-color);\n --tabs-font-color: var(--body-font-color);\n --tabs-selected-background-color: var(--selected-background-color);\n --tabs-selected-font-color: var(--body-background-color);\n --tabs-hover-font-color: var(--hover-link-font-color);\n --tabs-hover-background: var(--color-accent-1);\n --tabs-group-background-color: var(--panel-group-background-color);\n\n /* TOC */\n --toc-width: 24rem;\n --toc-display: block;\n --toc-font-color: var(--body-font-color);\n --toc-hover-background-color: var(--color-accent-1);\n --toc-active-background-color: var(--selected-background-color);\n --toc-active-font-color: var(--body-background-color);\n --toc-back-to-index-filter: none;\n --toc-bar-display: none;\n --toc-bar-height: 0;\n --toc-bar-button-filter: none;\n\n /* Code Tools */\n --codetools-button-filter: none;\n --codetools-button-active-filter: invert();\n --codetools-background-color: var(--body-background-color);\n --codetools-border-color: rgba(0, 0, 0, 0.3);\n --codetools-hover-background-color: var(--color-accent-1);\n --codetools-divider-color: var(--codetools-border-color);\n --codetools-popup-background-color: var(--selected-background-color);\n --codetools-popup-font-color: var(--body-background-color);\n}\n\n/* Responsive Overrides */\n\n@media screen and (max-width: 1024px) {\n :root {\n --toc-width: 16rem;\n --asciidoctor-doc-embellishment-margin-width: 140px;\n }\n}\n\n@media screen and (max-width: 800px) {\n :root {\n --layout-banner-height: 51px;\n --layout-banner-logo-height: 30px;\n --layout-banner-logo-offset: 10px;\n --layout-border-color: var(--body-background-color);\n --toc-bar-display: block;\n --toc-bar-height: 24px;\n --toc-width: 0;\n --toc-display: none;\n --asciidoctor-doc-embellishment-margin-width: 0;\n }\n}\n","html.dark-theme {\n /* General */\n --font-weight: 300;\n --body-background-color: #1b1f23;\n --panel-background-color: #262a2d;\n --panel-group-background-color: #303741;\n --panel-border-color: #2c3135;\n --color-accent-1: #272c33;\n --color-accent-1-invert: #d8d3cc;\n --color-accent-2: #2d333a;\n --color-accent-3: #6db33f;\n --body-font-color: #bbbcbe;\n --body-font-light-color: #abacaf;\n --body-font-dark-color: #cecfd1;\n --link-font-color: #086dc3;\n --hover-link-font-color: #107ddd;\n --scrollbar-thumb-color: #5f5f5f;\n --mark-background-color: #2eca12;\n --selected-background-color: #8d8d8d;\n\n /* Layout */\n --layout-switchtheme-invert-filter: none;\n --layout-switchtheme-background-color: var(--selected-background-color);\n\n /* Asciidoctor */\n --asciidoctor-code-background: rgba(177, 209, 241, 0.15);\n --asciidoctor-code-data-lang-color: #6e6e6e;\n --asciidoctor-admonition-font-color: #f0f0f0;\n --asciidoctor-admonition-caution-background: #603668;\n --asciidoctor-admonition-important-background: #924040;\n --asciidoctor-admonition-note-background: #355463;\n --asciidoctor-admonition-tip-background: #4d6340;\n --asciidoctor-admonition-warning-background: #967745;\n --asciidoctor-footer-font-color: #5e5e5e;\n\n /* Highlight JS (colors based on https://github.com/primer/github-syntax-dark) */\n --highlight-background-color: var(--asciidoctor-pre-background);\n --highlight-font-color: #f6f8fa;\n --highlight-keyword-font-color: #ea4a5a;\n --highlight-comment-font-color: #959da5;\n --highlight-string-font-color: #79b8ff;\n --highlight-meta-font-color: #959da5;\n --highlight-constant-font-color: #79b8ff;\n --highlight-variable-font-color: #c8e1ff;\n --highlight-tag-font-color: #7bcc72;\n --highlight-tag-attribute-font-color: #b392f0;\n --highlight-type-font-color: #b392f0;\n --highlight-link-font-color: #1565c0;\n --highlight-addition-font-color: #7bcc72;\n --highlight-deletion-font-color: #f6f8fa;\n --highlight-regex-font-color: #79b8ff;\n\n /* TOC */\n --toc-back-to-index-filter: invert();\n --toc-bar-button-filter: invert();\n\n /* Code Tools */\n --codetools-button-filter: invert();\n --codetools-button-active-filter: none;\n --codetools-hover-background-color: var(--color-accent-1-invert);\n --codetools-border-color: rgba(255, 255, 255, 0.274);\n --codetools-divider-color: rgba(44, 44, 44, 0.274);\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nhtml {\n box-sizing: border-box;\n}\n\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\nbody {\n text-size-adjust: none;\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nhtml {\n height: 100%;\n font-size: var(--html-font-size);\n scroll-behavior: smooth;\n min-width: 340px;\n}\n\nbody {\n margin: 0;\n overflow-wrap: anywhere;\n overscroll-behavior: none;\n font-family: var(--font-family);\n font-weight: var(--font-weight);\n color: var(--body-font-color);\n background-color: var(--body-background-color);\n}\n\na {\n text-decoration: none;\n}\n\na:hover {\n text-decoration: underline;\n}\n\na:active {\n background-color: none;\n}\n\ncode,\nkbd,\npre {\n font-family: var(--monospace-font-family);\n}\n\n@supports (scrollbar-width: thin) {\n body * {\n scrollbar-width: thin;\n scrollbar-color: var(--scrollbar-thumb-color) transparent;\n }\n}\n\ntable {\n border-collapse: collapse;\n word-wrap: normal;\n}\n\nmark {\n background: var(--mark-background-color);\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#banner-container {\n height: var(--layout-banner-height);\n overflow: hidden;\n border-bottom: 1px solid var(--layout-border-color);\n}\n\n#banner {\n height: 100%;\n background: no-repeat top var(--layout-banner-logo-offset) left\n var(--layout-banner-logo-offset) / auto var(--layout-banner-logo-height);\n background-image: url(\"../img/banner-logo.svg\");\n}\n\n#doc {\n overflow: auto;\n}\n\n.contained {\n max-width: var(--layout-max-width);\n margin: 0 auto;\n}\n\ndiv#switch-theme,\n#switch-theme label {\n display: none;\n}\n\nhtml.js div#switch-theme {\n display: block;\n float: right;\n margin: 8px 6px 0 0;\n}\n\n#switch-theme input {\n appearance: none;\n position: relative;\n width: 40px;\n height: 22px;\n filter: var(--layout-switchtheme-invert-filter);\n background: no-repeat url(\"../img/octicons-16.svg#view-sun\") 90% 50% / 16px\n 16px,\n no-repeat url(\"../img/octicons-16.svg#view-moon\") 10% 50% / 16px 16px;\n background-color: var(--layout-switchtheme-background-color);\n border-radius: 25px;\n outline: none;\n}\n\n#switch-theme input::before {\n filter: var(--layout-switchtheme-invert-filter);\n content: \"\";\n position: absolute;\n left: 2px;\n top: 2px;\n height: 18px;\n width: 18px;\n border-radius: 25px;\n background-color: var(--layout-switchtheme-button-color);\n transition: transform 200ms;\n}\n\n#switch-theme:hover input::before {\n background-color: var(--layout-switchtheme-button-hover-color);\n}\n\n#switch-theme input:checked::before {\n transform: translateX(18px);\n}\n","/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n/* Asciidoctor styling based on https://gitlab.com/antora/antora-ui-default/-/blob/8751b86b76d6779fbbcf0fccd58fafcf73c49260/src/css/doc.css */\n\n/* Container element styling */\n\n.doc {\n color: var(--asciidoctor-font-color);\n hyphens: none;\n line-height: 1.6;\n letter-spacing: -0.0027777778rem;\n margin: 0;\n}\n\n/* Gutter and margins */\n\n.doc #content,\n.doc #footer {\n margin: 0 2rem;\n}\n\n.doc #header > *:not(#toc) {\n /* Gutter is not applied directly to #header of toc positioning */\n margin-left: 2rem;\n margin-right: 2rem;\n}\n\n.doc #content {\n padding-bottom: 4rem;\n}\n\n/* Doc background embellishment */\n\n#doc {\n background: no-repeat top right / 305px 147px;\n background-image: url(\"../img/doc-background.svg\");\n}\n\n.doc #header {\n margin-right: var(--asciidoctor-doc-embellishment-margin-width);\n}\n\n/* Header Details */\n\n.doc #header .details {\n background: var(--asciidoctor-details-background);\n color: var(--asciidoctor-details-font-color);\n padding: 1rem 1.5rem;\n font-weight: 600;\n font-size: 0.8em;\n}\n\n.doc #header div.details {\n display: flex;\n flex-wrap: wrap;\n}\n\n#header .details br {\n display: none;\n}\n\n.doc #header .details span.author:not(:last-of-type)::after {\n content: \"\\2022\";\n font-weight: 400;\n margin: 0.4em;\n color: var(--asciidoctor-author-separator-color);\n}\n\n.doc #header .details span.last-author::after {\n display: none;\n}\n\n.doc #header .details #revnumber {\n flex-basis: 100%;\n margin-top: 0.5rem;\n text-transform: capitalize;\n font-weight: 200;\n}\n\n/* Section setup */\n\n.doc #preamble + .sect1,\n.doc .sect1 + .sect1 {\n margin-top: 2rem;\n}\n\n.doc .sect1 + .sect1 {\n border-top: 1px solid var(--asciidoctor-section-divider-color);\n}\n\n/* Headings */\n\n.doc h1 {\n font-size: 2.3em;\n}\n\n.doc h2 {\n font-size: 2em;\n}\n\n.doc h3 {\n font-size: 1.7em;\n}\n\n.doc h4 {\n font-size: 1.6em;\n}\n\n.doc h5 {\n font-size: 1.4em;\n}\n\n.doc h6 {\n font-size: 1.3em;\n}\n\n.doc h1,\n.doc h2,\n.doc h3,\n.doc h4,\n.doc h5,\n.doc h6 {\n color: var(--asciidoctor-heading-font-color);\n font-weight: var(--asciidoctor-heading-font-weight);\n hyphens: none;\n line-height: 1.3;\n margin: 1.3rem 0 0;\n padding-top: 1.8rem;\n}\n\n.doc h1.sect0 {\n background: var(--asciidoctor-abstract-background);\n font-size: 1.8em;\n margin: 1.5rem -1rem 0;\n padding: 0.5rem 1rem;\n}\n\n.doc h1:first-child {\n margin: 1.3rem 0;\n}\n\n.doc h2:not(.discrete) {\n margin-left: -1rem;\n margin-right: -1rem;\n padding: 1.8rem 1rem 0.1rem;\n}\n\n.doc h3:not(.discrete) {\n font-weight: var(--asciidoctor-alt-heading-font-weight);\n}\n\n/* Header hover anchors */\n\n.doc h1 .anchor,\n.doc h2 .anchor,\n.doc h3 .anchor,\n.doc h4 .anchor,\n.doc h5 .anchor,\n.doc h6 .anchor {\n position: absolute;\n text-decoration: none;\n width: 2.25ex;\n margin-left: -2ex;\n padding-left: 0.5ex;\n visibility: hidden;\n font-weight: normal;\n}\n\n.doc h1 .anchor::before,\n.doc h2 .anchor::before,\n.doc h3 .anchor::before,\n.doc h4 .anchor::before,\n.doc h5 .anchor::before,\n.doc h6 .anchor::before {\n content: \"\\0023\";\n}\n\n.doc h1:hover .anchor,\n.doc h2:hover .anchor,\n.doc h3:hover .anchor,\n.doc h4:hover .anchor,\n.doc h5:hover .anchor,\n.doc h6:hover .anchor {\n visibility: visible;\n}\n\n.doc p,\n.doc dl {\n margin: 0;\n}\n\n/* General anchors */\n\n.doc a.bare {\n hyphens: none;\n}\n\n.doc a {\n color: var(--asciidoctor-link-font-color);\n}\n\n.doc a:hover {\n color: var(--asciidoctor-hover-link-font-color);\n}\n\n.doc a.unresolved {\n color: var(--asciidoctor-unresolved-link-font-color);\n}\n\n/* Code and Pre */\n\n.doc p code,\n.doc thead code,\n.doc .admonitionblock code {\n color: var(--asciidoctor-code-font-color);\n background: var(--asciidoctor-code-background);\n border-radius: 0.25em;\n font-size: 0.95em;\n padding: 0.125em 0.25em;\n}\n\n.doc p a code,\n.doc thead a code,\n.doc .admonitionblock a code {\n color: var(--asciidoctor-code-link-font-color);\n}\n\n.doc code,\n.doc pre {\n hyphens: none;\n}\n\n.doc pre {\n font-size: calc(14 / var(--pixel-to-rem));\n line-height: 1.3;\n margin: 0;\n}\n\n.doc pre.highlight code,\n.doc .listingblock pre:not(.highlight),\n.doc .literalblock pre {\n background: var(--asciidoctor-pre-background);\n box-shadow: inset 0 0 1.75px var(--asciidoctor-pre-border-color);\n display: block;\n overflow-x: auto;\n padding: 0.95rem;\n border-radius: 4px;\n}\n\n.doc pre.highlight code[data-lang]:before {\n content: attr(data-lang);\n text-transform: uppercase;\n display: block;\n position: absolute;\n top: 0.3rem;\n right: 0.3rem;\n line-height: 1;\n font-size: 0.65em;\n color: var(--asciidoctor-code-data-lang-color);\n}\n\n.doc pre.highlight {\n position: relative;\n}\n\n.doc table pre.highlight code[data-lang]:before {\n display: none;\n}\n\n/* General margin and fonts sizing */\n\n.doc blockquote {\n margin: 0;\n}\n\n.doc .paragraph.lead > p {\n font-size: calc(18 / var(--pixel-to-rem));\n}\n\n.doc .paragraph,\n.doc .dlist,\n.doc .hdlist,\n.doc .olist,\n.doc .ulist,\n.doc .exampleblock,\n.doc .imageblock,\n.doc .listingblock,\n.doc .literalblock,\n.doc .sidebarblock,\n.doc .verseblock,\n.doc .quoteblock,\n.doc .partintro,\n.doc details,\n.doc hr {\n margin: 1rem 0 0;\n}\n\n/* Tables */\n\n.doc table.tableblock {\n display: block;\n width: 100%;\n overflow-x: auto;\n}\n\n.doc table.tableblock td {\n min-width: 6rem;\n}\n\n.doc table.tableblock {\n font-size: calc(15 / var(--pixel-to-rem));\n margin: 1.5rem 0 0;\n}\n\n.doc table.tableblock + * {\n margin-top: 2rem;\n}\n\n.doc td.tableblock > .content > :first-child {\n margin-top: 0;\n}\n\n.doc table.tableblock th,\n.doc table.tableblock td {\n padding: 0.5rem;\n}\n\n.doc table.tableblock thead th {\n border-bottom: 2.5px solid var(--asciidoctor-table-border-color);\n}\n\n.doc table.tableblock td,\n.doc table.tableblock > :not(thead) th {\n border-top: 1px solid var(--asciidoctor-table-border-color);\n border-bottom: 1px solid var(--asciidoctor-table-border-color);\n}\n\n.doc table.stripes-all > tbody > tr,\n.doc table.stripes-odd > tbody > tr:nth-of-type(odd),\n.doc table.stripes-even > tbody > tr:nth-of-type(even),\n.doc table.stripes-hover > tbody > tr:hover {\n background: var(--asciidoctor-table-stripe-background);\n}\n\n.doc table.tableblock > tfoot {\n background: var(--asciidoctor-table-footer-background);\n}\n\n.doc .tableblock pre,\n.doc .tableblock code,\n.doc .listingblock.wrap pre {\n white-space: pre-wrap;\n}\n\n.doc td:nth-child(1) .tableblock pre,\n.doc td:nth-child(1) .tableblock code,\n.doc td:nth-child(1) .listingblock.wrap pre {\n white-space: nowrap;\n}\n\n/* Admonition blocks */\n\n.doc .admonitionblock {\n margin: 2.5rem 0;\n}\n\n.doc .admonitionblock p,\n.doc .admonitionblock td.content {\n font-size: calc(16 / var(--pixel-to-rem));\n}\n\n.doc .admonitionblock td.content > :not(.title):first-child,\n.doc .admonitionblock td.content > .title + * {\n margin-top: 0;\n}\n\n.doc .admonitionblock pre {\n font-size: calc(14 / var(--pixel-to-rem));\n border: none;\n}\n\n.doc .admonitionblock > table {\n table-layout: fixed;\n position: relative;\n width: 100%;\n}\n\n.doc .admonitionblock td.content {\n padding: 1rem 1rem 0.75rem;\n background: var(--asciidoctor-admonition-background);\n width: 100%;\n word-wrap: anywhere;\n}\n\n.doc .admonitionblock td.icon {\n position: absolute;\n top: 0;\n left: 0;\n font-size: calc(16 / var(--pixel-to-rem));\n line-height: 1;\n transform: translate(-0.5rem, -50%);\n border-radius: 0.45rem;\n padding: 0.25em 0.075em;\n}\n\n.doc .admonitionblock .icon i {\n display: inline-flex;\n align-items: center;\n width: auto;\n height: 16px;\n background-repeat: no-repeat;\n background-position: 0.5em 0;\n filter: invert(100%);\n padding-left: 2em;\n vertical-align: initial;\n}\n\n.doc .admonitionblock .icon i::after {\n border-left: 1px solid rgba(255, 255, 255, 0.3);\n content: attr(title);\n text-transform: capitalize;\n filter: invert(100%);\n font-weight: var(--asciidoctor-admonition-label-font-weight);\n color: var(--asciidoctor-admonition-font-color);\n font-style: normal;\n hyphens: none;\n padding: 0 0.5em;\n margin: -0.05em;\n}\n\ni.fa {\n background-size: 16px 16px;\n}\n\ni.fa.icon-caution {\n background-image: url(\"../img/octicons-16.svg#view-flame\");\n}\n\ni.fa.icon-important {\n background-image: url(\"../img/octicons-16.svg#view-stop\");\n}\n\ni.fa.icon-note {\n background-image: url(\"../img/octicons-16.svg#view-info\");\n}\n\ni.fa.icon-tip {\n background-image: url(\"../img/octicons-16.svg#view-light-bulb\");\n}\n\ni.fa.icon-warning {\n background-image: url(\"../img/octicons-16.svg#view-alert\");\n}\n\n.doc .admonitionblock.caution td.icon {\n background: var(--asciidoctor-admonition-caution-background);\n}\n\n.doc .admonitionblock.important td.icon {\n background: var(--asciidoctor-admonition-important-background);\n}\n\n.doc .admonitionblock.note .icon {\n background: var(--asciidoctor-admonition-note-background);\n}\n\n.doc .admonitionblock.tip .icon {\n background: var(--asciidoctor-admonition-tip-background);\n}\n\n.doc .admonitionblock.warning .icon {\n background-color: var(--asciidoctor-admonition-warning-background);\n}\n\n/* Images and image blocks */\n\n.doc .imageblock {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.doc .imageblock img,\n.doc .image > img {\n display: inline-block;\n height: auto;\n max-width: 100%;\n vertical-align: middle;\n}\n\n.doc .image:not(.left):not(.right) > img {\n margin-top: -0.2em;\n}\n\n/* Quote blocks */\n\n.doc #preamble .abstract blockquote {\n background: var(--asciidoctor-abstract-background);\n border-left: 5px solid var(--asciidoctor-abstract-border-color);\n font-size: calc(16 / var(--pixel-to-rem));\n padding: 0.75em 1em;\n}\n\n.doc .quoteblock,\n.doc .verseblock {\n background: var(--asciidoctor-quote-background);\n border-left: 5px solid var(--asciidoctor-quote-border-color);\n}\n\n.doc .quoteblock {\n padding: 0.25rem 2rem 1.25rem;\n}\n\n.doc .quoteblock .attribution {\n color: var(--asciidoctor-quote-attribution-font-color);\n font-size: calc(15 / var(--pixel-to-rem));\n margin-top: 0.75rem;\n}\n\n.doc .quoteblock blockquote {\n margin-top: 1rem;\n}\n\n.doc .quoteblock .paragraph {\n font-style: italic;\n}\n\n.doc .quoteblock cite {\n padding-left: 1em;\n}\n\n/* Verse blocks */\n\n.doc .verseblock {\n font-size: 1.15em;\n padding: 1rem 2rem;\n}\n\n.doc .verseblock pre {\n font-family: inherit;\n font-size: inherit;\n}\n\n/* Lists */\n\n.doc ol,\n.doc ul {\n margin: 0;\n padding: 0 0 0 2rem;\n}\n\n.doc ul.checklist,\n.doc ul.none,\n.doc ol.none,\n.doc ul.no-bullet,\n.doc ol.unnumbered,\n.doc ul.unstyled,\n.doc ol.unstyled {\n list-style-type: none;\n}\n\n.doc ul.no-bullet,\n.doc ol.unnumbered {\n padding-left: 1.25rem;\n}\n\n.doc ul.unstyled,\n.doc ol.unstyled {\n padding-left: 0;\n}\n\n.doc ul.circle {\n list-style-type: square;\n}\n\n.doc ul.disc {\n list-style-type: square;\n}\n\n.doc ul.square {\n list-style-type: square;\n}\n\n.doc ol.arabic {\n list-style-type: decimal;\n}\n\n.doc ol.decimal {\n list-style-type: decimal-leading-zero;\n}\n\n.doc ol.loweralpha {\n list-style-type: lower-alpha;\n}\n\n.doc ol.upperalpha {\n list-style-type: upper-alpha;\n}\n\n.doc ol.lowerroman {\n list-style-type: lower-roman;\n}\n\n.doc ol.upperroman {\n list-style-type: upper-roman;\n}\n\n.doc ol.lowergreek {\n list-style-type: lower-greek;\n}\n\n.doc ul.checklist {\n padding-left: 0.5rem;\n}\n\n.doc ul.checklist p > i.fa-check-square-o:first-child,\n.doc ul.checklist p > i.fa-square-o:first-child {\n display: inline-flex;\n justify-content: center;\n width: 1.25rem;\n}\n\n.doc ul.checklist i.fa-check-square-o::before {\n content: \"\\2713\";\n}\n\n.doc ul.checklist i.fa-square-o::before {\n content: \"\\274f\";\n}\n\n.doc .dlist .dlist,\n.doc .dlist .olist,\n.doc .dlist .ulist,\n.doc .olist .dlist,\n.doc .olist .olist,\n.doc .olist .ulist,\n.doc .ulist .dlist,\n.doc .ulist .olist,\n.doc .ulist .ulist {\n margin-top: 0.5rem;\n}\n\n.doc .olist li,\n.doc .ulist li {\n margin-bottom: 0.3rem;\n}\n\n.doc .ulist .listingblock,\n.doc .olist .listingblock,\n.doc .admonitionblock .listingblock {\n padding: 0;\n}\n\n/* Block Titles */\n\n.doc .admonitionblock .title,\n.doc .exampleblock .title,\n.doc .imageblock .title,\n.doc .literalblock .title,\n.doc .listingblock .title,\n.doc .openblock .title,\n.doc .tableblock caption {\n color: var(--asciidoctor-caption-font-color);\n font-size: calc(14 / var(--pixel-to-rem));\n font-weight: var(--asciidoctor-caption-font-weight);\n font-style: italic;\n hyphens: none;\n letter-spacing: 0.01em;\n padding-bottom: 0.075rem;\n text-align: left;\n}\n\n.doc .imageblock .title {\n margin-top: 0.5rem;\n padding-bottom: 0;\n}\n\n/* Block content */\n\n.doc .exampleblock > .content {\n background: var(--asciidoctor-example-background);\n border: 1px solid var(--asciidoctor-example-border-color);\n border-radius: 4px;\n padding: 0.75rem;\n}\n\n.doc .exampleblock > .content > :first-child {\n margin-top: 0;\n}\n\n/* Sidebars */\n\n.doc .sidebarblock {\n background: var(--asciidoctor-sidebar-background);\n padding: 2.2rem 2.2rem;\n}\n\n.doc .sidebarblock > .content > .title {\n font-size: calc(23 / var(--pixel-to-rem));\n font-weight: var(--asciidoctor-alt-heading-font-weight);\n line-height: 1.3;\n margin-bottom: 1.2rem;\n}\n\n.doc .sidebarblock > .content > :not(.title):first-child {\n margin-top: 0;\n}\n\n/* Buttons (https://docs.asciidoctor.org/asciidoc/latest/macros/ui-macros/#button-macro-syntax) */\n\n.doc b.button {\n white-space: nowrap;\n}\n\n.doc b.button::before {\n content: \"[\";\n padding-right: 0.25em;\n}\n\n.doc b.button::after {\n content: \"]\";\n padding-left: 0.25em;\n}\n\n/* Menu (https://docs.asciidoctor.org/asciidoc/latest/macros/ui-macros/#menu-macro-syntax) */\n\n.doc .menuseq,\n.doc .path {\n hyphens: none;\n}\n\n.doc .menuseq i.caret::before {\n content: \"\\203a\";\n font-size: 1.1em;\n font-weight: var(--asciidoctor-body-font-weight-bold);\n line-height: calc(1 / 1.1);\n}\n\n/* Keyboard (https://docs.asciidoctor.org/asciidoc/latest/macros/keyboard-macro/) */\n\n.doc kbd {\n display: inline-block;\n font-size: calc(12 / var(--pixel-to-rem));\n background: var(--asciidoctor-kbd-background);\n border: 1px solid var(--asciidoctor-kbd-border-color);\n border-radius: 0.25em;\n box-shadow: 0 1px 0 var(--asciidoctor-kbd-border-color),\n 0 0 0 0.1em var(--body-background) inset;\n padding: 0.25em 0.5em;\n vertical-align: text-bottom;\n white-space: nowrap;\n}\n\n.doc kbd,\n.doc .keyseq {\n line-height: 1;\n}\n\n.doc .keyseq {\n font-size: calc(16 / var(--pixel-to-rem));\n}\n\n.doc .keyseq kbd {\n margin: 0 0.125em;\n}\n\n.doc .keyseq kbd:first-child {\n margin-left: 0;\n}\n\n.doc .keyseq kbd:last-child {\n margin-right: 0;\n}\n\n/* Misc */\n\n.doc i.fa {\n hyphens: none;\n font-style: normal;\n}\n\n.doc .language-console .hljs-meta {\n user-select: none;\n}\n\n.doc .dlist dt {\n font-style: italic;\n}\n\n.doc .dlist dd {\n margin: 0 0 0.25rem 1.5rem;\n}\n\n.doc .dlist dd:last-of-type {\n margin-bottom: 0;\n}\n\n.doc td.hdlist1,\n.doc td.hdlist2 {\n padding: 0.5rem 0 0;\n vertical-align: top;\n}\n\n.doc tr:first-child > .hdlist1,\n.doc tr:first-child > .hdlist2 {\n padding-top: 0;\n}\n\n.doc td.hdlist1 {\n font-weight: var(--body-font-weight-bold);\n padding-right: 0.25rem;\n}\n\n.doc td.hdlist2 {\n padding-left: 0.25rem;\n}\n\n.doc .colist {\n font-size: calc(16 / var(--pixel-to-rem));\n margin: 0.25rem 0 -0.25rem;\n}\n\n.doc .colist > table > tr > :first-child,\n.doc .colist > table > tbody > tr > :first-child {\n padding: 0.25em 0.5rem 0;\n vertical-align: top;\n}\n\n.doc .colist > table > tr > :last-child,\n.doc .colist > table > tbody > tr > :last-child {\n padding: 0.25rem 0;\n}\n\n.doc .conum[data-value] {\n /* border: 1px solid currentColor; */\n font-family: var(--monospace-font-family);\n border-radius: 100%;\n display: inline-block;\n font-size: calc(12.5 / var(--pixel-to-rem));\n font-style: normal;\n line-height: 1.2;\n text-align: center;\n width: 1.25em;\n height: 1.25em;\n letter-spacing: -0.25ex;\n text-indent: -0.25ex;\n background: var(--asciidoctor-callout-background);\n color: var(--asciidoctor-callout-font-color);\n}\n\n.doc .conum[data-value]::after {\n content: attr(data-value);\n}\n\n.doc .conum[data-value] + b {\n display: none;\n}\n\n.doc hr {\n border: solid var(--asciidoctor-section-divider-color);\n border-width: 2px 0 0;\n height: 0;\n}\n\n/* Pass-though Classes */\n\n.doc :not(pre).nowrap {\n white-space: nowrap;\n}\n\n.doc .nobreak {\n hyphens: none;\n word-wrap: normal;\n}\n\n.doc .right {\n float: right;\n}\n\n.doc .left {\n float: left;\n}\n\n.doc .stretch {\n width: 100%;\n}\n\n.doc .underline {\n text-decoration: underline;\n}\n\n.doc .line-through {\n text-decoration: line-through;\n}\n\n.doc .halign-left {\n text-align: left;\n}\n\n.doc .halign-right {\n text-align: right;\n}\n\n.doc .halign-center {\n text-align: center;\n}\n\n.doc .valign-top {\n vertical-align: top;\n}\n\n.doc .valign-bottom {\n vertical-align: bottom;\n}\n\n.doc .valign-middle {\n vertical-align: middle;\n}\n\n/* Footer */\n\n#footer #footer-text {\n font-size: calc(14 / var(--pixel-to-rem));\n color: var(--asciidoctor-footer-font-color);\n padding: 2rem 0;\n border-top: 1px solid var(--asciidoctor-section-divider-color);\n}\n\n/* Responsive and Dark Theme Overrides */\n\nhtml.dark-theme #doc {\n background: no-repeat top right / 305px 147px;\n background-image: url(\"../img/doc-background-dark.svg\");\n}\n\n@media screen and (max-width: 1024px) {\n #doc {\n background: no-repeat top right / 203px 95px;\n background-image: url(\"../img/doc-background.svg\");\n }\n html.dark-theme #doc {\n background: no-repeat top right / 203px 95px;\n background-image: url(\"../img/doc-background-dark.svg\");\n }\n}\n\n@media screen and (max-width: 800px) {\n html.dark-theme #doc,\n #doc {\n background: none;\n }\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n.hljs {\n display: block;\n overflow-x: auto;\n padding: 0.5em;\n background: var(--highlight-background-color);\n color: var(--highlight-font-color);\n}\n\n.hljs-keyword,\n.hljs-selector-tag,\n.hljs-subst {\n color: var(--highlight-keyword-font-color);\n}\n\n.hljs-comment,\n.hljs-quote {\n color: var(--highlight-comment-font-color);\n}\n\n.hljs-string,\n.hljs-doctag {\n color: var(--highlight-string-font-color);\n}\n\n.hljs-meta {\n color: var(--highlight-meta-font-color);\n}\n\n.hljs-built_in,\n.hljs-builtin-name,\n.hljs-number,\n.hljs-symbol,\n.hljs-literal {\n color: var(--highlight-constant-font-color);\n}\n\n.hljs-variable,\n.hljs-template-variable {\n color: var(--highlight-variable-font-color);\n}\n\n.hljs-tag,\n.hljs-name,\n.hljs-attribute {\n color: var(--highlight-tag-font-color);\n}\n\n.hljs-tag .hljs-attr {\n color: var(--highlight-tag-attribute-font-color);\n}\n\n.hljs-type,\n.hljs-class .hljs-title {\n color: var(--highlight-type-font-color);\n}\n\n.hljs-regexp {\n color: var(--highlight-regex-font-color);\n}\n\n.hljs-link {\n text-decoration: underline;\n color: var(--highlight-link-font-color);\n}\n\n.hljs-addition {\n color: var(--highlight-addition-font-color);\n}\n\n.hljs-deletion {\n color: var(--highlight-deletion-font-color);\n}\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n\n.language-json .hljs-number,\n.language-json .hljs-literal {\n color: var(--highlight-variable-font-color);\n}\n\n.language-json .hljs-attr {\n color: var(--highlight-string-font-color);\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Block Switching */\n\n.hidden {\n display: none;\n}\n\n.doc .tabs {\n font-weight: bold;\n font-size: calc(12 / var(--pixel-to-rem));\n border-style: none;\n display: inline-block;\n position: relative;\n bottom: 0;\n margin-top: 0.5rem;\n margin-bottom: calc(2 / var(--pixel-to-rem));\n}\n\n.doc .tab:not(:first-child) {\n border: 1px solid var(--tabs-border-color);\n}\n\n.doc .tab {\n padding: 0.3rem 0.6rem;\n background-color: var(--tabs-background-color);\n color: var(--tabs-font-color);\n display: inline-block;\n cursor: pointer;\n border: 1px solid var(--tabs-border-color);\n margin-bottom: calc(2 / var(--pixel-to-rem));\n border-radius: 0;\n transition: background-color 200ms;\n}\n\n.doc .tab:hover {\n color: var(--tabs-hover-font-color);\n background-color: var(--tabs-hover-background);\n text-decoration: underline;\n}\n\n.doc .tab.selected {\n background-color: var(--tabs-selected-background-color);\n border-color: var(--tabs-selected-background-color);\n color: var(--tabs-selected-font-color);\n}\n\n.doc .tab.selected:hover {\n color: var(--tabs-selected-font-color);\n text-decoration: none;\n}\n\n.doc div.openblock.tabs-content > .content {\n padding: 1rem;\n background-color: var(--tabs-group-background-color);\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nbody.toc-left #doc {\n border-left: 1px solid var(--layout-border-color);\n overflow: auto;\n margin-left: var(--toc-width);\n}\n\n#toc {\n display: var(--toc-display);\n position: absolute;\n top: var(--layout-banner-height);\n width: var(--toc-width);\n margin-left: calc(var(--toc-width) * -1);\n border-right: 1px solid var(--layout-border-color);\n padding: 1.7rem 1rem 0 1rem;\n font-size: 0.95rem;\n line-height: 1.1;\n}\n\n#toctitle {\n display: none;\n}\n\n#toc ul,\n#toc ol {\n padding: 0;\n}\n\n#toc ul ul,\n#toc ul ol {\n padding-left: 0.8rem;\n}\n\n#toc li {\n display: block;\n list-style: none;\n}\n\n#toc a {\n display: block;\n text-decoration: none;\n color: var(--toc-font-color);\n padding: 0.4rem 0.6rem;\n border-radius: 4px;\n}\n\n#toc a:hover {\n background-color: var(--toc-hover-background-color);\n}\n\nbody.fixed-toc #toc {\n position: fixed;\n top: 0;\n overflow-x: hidden;\n height: 100%;\n}\n\n#toc li.active > a {\n background-color: var(--toc-active-background-color);\n color: var(--toc-active-font-color);\n}\n\n#toc > ul ul,\n#toc > ol ol {\n display: none;\n}\n\n#toc li.active > ul,\n#toc li.active > ol,\n#toc ul.expanded,\n#toc ol.expanded {\n display: block;\n}\n\n#back-to-index {\n display: block;\n margin-bottom: 0.6rem;\n}\n\n#back-to-index a {\n padding-left: 1.6rem;\n margin-bottom: 0.6rem;\n margin-top: -0.9rem;\n}\n\n#back-to-index a::before {\n content: \"\";\n filter: var(--toc-back-to-index-filter);\n background: no-repeat center / 16px 16px;\n background-image: url(\"../img/octicons-16.svg#view-chevron-left\");\n display: block;\n position: absolute;\n min-width: 16px;\n min-height: 16px;\n left: 1.4rem;\n}\n\n#tocbar-container {\n display: var(--toc-bar-display);\n width: 100%;\n}\n\n#tocbar-container {\n height: var(--tocbar-height);\n background-color: var(--body-background-color);\n border-bottom: 1px solid var(--panel-border-color);\n z-index: 10000;\n}\n\n#tocbar {\n width: 100%;\n height: 100%;\n padding-left: 6px;\n}\n\nbody.fixed-toc #tocbar-container {\n position: fixed;\n top: 0;\n}\n\nbutton#toggle-toc {\n width: var(--toc-bar-height);\n height: var(--toc-bar-height);\n filter: var(--toc-bar-button-filter);\n background: no-repeat center / 16px 16px;\n background-image: url(\"../img/octicons-16.svg#view-three-bars\");\n border: none;\n outline: none;\n padding: 0;\n display: block;\n}\n\nbody.show-toc button#toggle-toc {\n background-image: url(\"../img/octicons-16.svg#view-x\");\n}\n\n@media screen and (max-width: 800px) {\n body.fixed-toc #toc {\n top: var(--toc-bar-height);\n }\n\n #toc {\n top: calc(var(--layout-banner-height) + var(--toc-bar-height));\n width: 100%;\n height: 100%;\n left: 0;\n background-color: var(--body-background-color);\n z-index: 10000;\n }\n\n body.show-toc #toc {\n display: block;\n }\n}\n","/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ndiv.codetools {\n --button-width: 28px;\n --button-height: 24px;\n --arrow-size: 5px;\n display: flex;\n position: absolute;\n bottom: 9px;\n right: 8px;\n background: var(--codetools-background-color);\n padding: 0;\n border-radius: 2px;\n border: 1px solid var(--codetools-border-color);\n opacity: 0;\n transition: opacity 150ms ease-in-out;\n}\n\n.doc pre.highlight:hover div.codetools {\n opacity: 1;\n}\n\ndiv.codetools button {\n width: var(--button-width);\n height: var(--button-height);\n filter: var(--codetools-button-filter);\n background: no-repeat center / 16px 16px;\n border: none;\n padding: 0;\n outline: none;\n}\n\ndiv.codetools button:not(:last-child) {\n border-right: 1px solid var(--codetools-divider-color);\n}\n\ndiv.codetools button:hover {\n background-color: var(--codetools-hover-background-color);\n transition: filter 300ms;\n}\n\ndiv.codetools button:active {\n filter: var(--codetools-button-active-filter);\n transition: filter none;\n}\n\ndiv.codetools button span.label {\n display: none;\n}\n\ndiv.codetools button.copy-button {\n background-image: url(\"../img/octicons-16.svg#view-clippy\");\n}\n\ndiv.codetools button.unfold-button {\n background-image: url(\"../img/octicons-16.svg#view-unfold\");\n}\n\ndiv.codetools button.fold-button {\n background-image: url(\"../img/octicons-16.svg#view-fold\");\n}\n\ndiv.codetools span.copied {\n opacity: 0;\n display: block;\n content: \"\";\n position: relative;\n width: var(--button-width);\n height: var(--button-height);\n z-index: 1000000;\n transition: opacity 500ms;\n}\n\ndiv.codetools button:active span.copied {\n filter: invert();\n transition: filter none;\n}\n\ndiv.codetools span.copied:before {\n position: absolute;\n bottom: calc(var(--arrow-size) * -1);\n left: 50%;\n margin-left: calc(var(--arrow-size) / -2);\n content: \"\";\n border: var(--arrow-size) solid var(--codetools-popup-background-color);\n border-color: transparent transparent var(--codetools-popup-background-color)\n transparent;\n}\n\ndiv.codetools span.copied:after {\n content: \"Copied to clipboard!\";\n position: absolute;\n top: calc(var(--button-height) + var(--arrow-size));\n right: 100%;\n margin-right: calc(var(--button-width) * -1);\n background-color: var(--codetools-popup-background-color);\n color: var(--codetools-popup-font-color);\n padding: 5px 8px;\n border-radius: 3px;\n font-weight: bold;\n}\n\ndiv.codetools button.clicked span.copied {\n opacity: 1;\n}\n\nspan.fold-block {\n position: relative;\n float: left;\n clear: left;\n padding-right: 0.75rem;\n overflow: hidden;\n}\n\ncode.unfolded span.fold-block.hide-when-folded,\ncode:not(.unfolded) span.fold-block.hide-when-unfolded {\n max-height: 99999px;\n opacity: 1;\n}\n\ncode.unfolded span.fold-block.hide-when-unfolded,\ncode:not(.unfolded) span.fold-block.hide-when-folded {\n max-height: 0px;\n opacity: 0;\n}\n\ncode.unfolding span.fold-block.hide-when-folded {\n max-height: 600px;\n opacity: 1;\n}\n\ncode.folding span.fold-block.hide-when-unfolded {\n max-height: 400px;\n opacity: 1;\n}\n\ncode.unfolding span.fold-block.hide-when-unfolded,\ncode.folding span.fold-block.hide-when-folded {\n max-height: 0;\n opacity: 0;\n}\n\ncode.unfolding span.fold-block.hide-when-unfolded {\n transition: max-height 200ms cubic-bezier(0, 1, 0, 1), opacity 200ms linear;\n}\n\ncode.folding span.fold-block.hide-when-unfolded {\n transition: max-height 200ms cubic-bezier(1, 0, 1, 0), opacity 200ms linear;\n}\n\ncode.unfolding span.fold-block.hide-when-folded {\n transition: max-height 200ms cubic-bezier(1, 0, 1, 0), opacity 200ms linear;\n}\n\ncode.folding span.fold-block.hide-when-folded {\n transition: max-height 200ms cubic-bezier(0, 1, 0, 1), opacity 200ms linear;\n}\n"]} \ No newline at end of file diff --git a/applications/rest-service/pom.xml b/applications/spring-boot-upgrade/pom.xml similarity index 94% rename from applications/rest-service/pom.xml rename to applications/spring-boot-upgrade/pom.xml index b5957861d..405ddf879 100644 --- a/applications/rest-service/pom.xml +++ b/applications/spring-boot-upgrade/pom.xml @@ -24,7 +24,7 @@ ../../pom.xml - rest-service + spring-boot-upgrade jar @@ -71,10 +71,12 @@ spring-asciidoctor-backends - spring-boot-upgrade + + spring-boot-upgrade + diff --git a/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/ReportController.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/ReportController.java new file mode 100644 index 000000000..6f9f70c0c --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/ReportController.java @@ -0,0 +1,83 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm; + +import lombok.Getter; +import lombok.Setter; +import lombok.Value; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportRenderer; +import org.springframework.sbm.engine.commands.ApplyCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@Controller +@CrossOrigin +class ReportController{ + + @Autowired + private ApplyCommand applyCommand; + @Autowired + private ReportHolder reportHolder; + + @Autowired + private ProjectContextHolder contextHolder; + + public static final String REPORT_RECIPE = "sbu30-report"; + + private boolean isInitialReport = true; + + @GetMapping(path = "/spring-boot-upgrade", produces = MediaType.TEXT_HTML_VALUE) + @ResponseBody + public String upgrade() { + // Urgh... that's nasty + if(!isInitialReport) { + applyCommand.execute(contextHolder.getProjectContext(), REPORT_RECIPE); + } + isInitialReport = false; + return reportHolder.getReport(); + } + + @PostMapping(path = "/spring-boot-upgrade", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, produces = MediaType.TEXT_HTML_VALUE) + @ResponseBody + public String applyRecipes(@RequestParam("recipeNames[]") String[] recipeNames) { + ProjectContext context = contextHolder.getProjectContext(); + List.of(recipeNames).forEach(recipeName -> applyCommand.execute(context, recipeName)); + applyCommand.execute(context, REPORT_RECIPE); + return reportHolder.getReport(); + } + + @PostMapping(path = "/spring-boot-upgrade") + @ResponseBody + public void applyRecipes2(@RequestBody Recipe recipeNames) { + ProjectContext context = contextHolder.getProjectContext(); + recipeNames.getRecipes().forEach( + recipeName -> applyCommand.execute(context, recipeName) + ); + applyCommand.execute(context, REPORT_RECIPE); + } + + @Getter + @Setter + static class Recipe { + private List recipes; + } +} diff --git a/applications/rest-service/src/main/java/org/springframework/sbm/ReportHolder.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/ReportHolder.java similarity index 100% rename from applications/rest-service/src/main/java/org/springframework/sbm/ReportHolder.java rename to applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/ReportHolder.java diff --git a/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootMigratorRunner.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootMigratorRunner.java new file mode 100644 index 000000000..00eded060 --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootMigratorRunner.java @@ -0,0 +1,51 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm; + +import lombok.RequiredArgsConstructor; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.sbm.engine.commands.ApplyCommand; +import org.springframework.sbm.engine.commands.ScanCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextHolder; + +@Configuration +@RequiredArgsConstructor +public class SpringBootMigratorRunner implements ApplicationRunner { + + private final ScanCommand scanCommand; + private final ProjectContextHolder contextHolder; + private final ApplyCommand applyCommand; + private final String REPORT_RECIPE = "sbu30-report"; + + @Override + public void run(ApplicationArguments args) { + if (args.getSourceArgs().length == 0) { + System.err.println("PLease provide the path to the application as parameter."); + return; + } + String applicationPath = args.getSourceArgs()[0]; + System.out.println("Scanning " + applicationPath); + ProjectContext context = scanCommand.execute(applicationPath); + contextHolder.setProjectContext(context); + applyCommand.execute(contextHolder.getProjectContext(), REPORT_RECIPE); + System.out.println("finished scan. Please open: http://localhost:8080/spring-boot-upgrade"); + } + + +} diff --git a/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootUpgradeReportApp.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootUpgradeReportApp.java new file mode 100644 index 000000000..5a38f5f8a --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootUpgradeReportApp.java @@ -0,0 +1,47 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @author Fabian Krüger + */ +@SpringBootApplication +public class SpringBootUpgradeReportApp { + public static void main(String[] args) { + try { + SpringApplication.run(SpringBootUpgradeReportApp.class, args); + } catch (Exception exception) { + System.err.println(exception.getMessage()); + exception.printStackTrace(); + } + } + + @Bean + public WebMvcConfigurer corsConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**").allowedMethods("*"); + } + }; + } +} diff --git a/applications/rest-service/src/main/java/org/springframework/sbm/SpringBootUpgradeReportStringRenderer.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootUpgradeReportStringRenderer.java similarity index 53% rename from applications/rest-service/src/main/java/org/springframework/sbm/SpringBootUpgradeReportStringRenderer.java rename to applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootUpgradeReportStringRenderer.java index d055a0633..66ca2af0e 100644 --- a/applications/rest-service/src/main/java/org/springframework/sbm/SpringBootUpgradeReportStringRenderer.java +++ b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/SpringBootUpgradeReportStringRenderer.java @@ -27,12 +27,28 @@ @Component @Primary public class SpringBootUpgradeReportStringRenderer implements SpringBootUpgradeReportRenderer { - @Autowired private ReportHolder reportHolder; @Override public void processReport(String renderedReport) { String htmlReport = UpgradeReportUtil.renderHtml(renderedReport); + String closingHeadTag = ""; + + String additionalHeader = +// "\n" + +// "\n" + +// "\n" + + +// "\n"; +// htmlReport = htmlReport.replace(closingHeadTag, additionalHeader + closingHeadTag); + + htmlReport = htmlReport.replace("", """ + + + + + + """); reportHolder.setReport(htmlReport); } } diff --git a/applications/rest-service/src/main/java/org/springframework/sbm/service/RestApi.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/service/RestApi.java similarity index 100% rename from applications/rest-service/src/main/java/org/springframework/sbm/service/RestApi.java rename to applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/service/RestApi.java diff --git a/applications/rest-service/src/main/java/org/springframework/sbm/service/SbmRestApiConfig.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/service/SbmRestApiConfig.java similarity index 100% rename from applications/rest-service/src/main/java/org/springframework/sbm/service/SbmRestApiConfig.java rename to applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/service/SbmRestApiConfig.java diff --git a/applications/rest-service/src/main/java/org/springframework/sbm/service/dto/RecipeInfo.java b/applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/service/dto/RecipeInfo.java similarity index 100% rename from applications/rest-service/src/main/java/org/springframework/sbm/service/dto/RecipeInfo.java rename to applications/spring-boot-upgrade/src/main/java/org/springframework/sbm/service/dto/RecipeInfo.java diff --git a/applications/spring-boot-upgrade/src/main/resources/application.properties b/applications/spring-boot-upgrade/src/main/resources/application.properties new file mode 100644 index 000000000..cc9de811a --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/application.properties @@ -0,0 +1,10 @@ +spring.profiles.active=default, core +spring.application.name=spring-boot-upgrade-report +# toggle support for git to sync and auto-commit +sbm.gitSupportEnabled=true +logging.level.org=ERROR +logging.level.org.springframework.sbm.logging.MethodCallTraceInterceptor=DEBUG +logging.level.org.springframework.sbm.logging.StopWatchTraceInterceptor=DEBUG +logging.level.org.springframework=ERROR +logging.level.org.openrewrite=ERROR +logging.level.org.springframework.sbm=ERROR \ No newline at end of file diff --git a/applications/spring-boot-upgrade/src/main/resources/banner.txt b/applications/spring-boot-upgrade/src/main/resources/banner.txt new file mode 100644 index 000000000..e16e965b9 --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/banner.txt @@ -0,0 +1,27 @@ + + _____ _ ______ _ _____ +/ ___| (_) | ___ \ | | |____ | +\ `--. _ __ _ __ _ _ __ __ _ | |_/ / ___ ___ | |_ / / + `--. \ '_ \| '__| | '_ \ / _` | | ___ \/ _ \ / _ \| __| \ \ +/\__/ / |_) | | | | | | | (_| | | |_/ / (_) | (_) | |_ .___/ / +\____/| .__/|_| |_|_| |_|\__, | \____/ \___/ \___/ \__| \____/ + | | __/ | + |_| |___/ + _ _ _ ______ _ +| | | | | | | ___ \ | | +| | | |_ __ __ _ _ __ __ _ __| | ___ | |_/ /___ _ __ ___ _ __| |_ +| | | | '_ \ / _` | '__/ _` |/ _` |/ _ \ | // _ \ '_ \ / _ \| '__| __| +| |_| | |_) | (_| | | | (_| | (_| | __/ | |\ \ __/ |_) | (_) | | | |_ + \___/| .__/ \__, |_| \__,_|\__,_|\___| \_| \_\___| .__/ \___/|_| \__| + | | __/ | | | + |_| |___/ |_| + +powered by Spring Boot Migrator + +------------------------------------------------------------------------- + +Find us on GitHub: https://via.vmw.com/8AD63p + +Please report all errors: https://via.vmw.com/bXlqJC + +------------------------------------------------------------------------- diff --git a/applications/spring-boot-upgrade/src/main/resources/static/css/button.css b/applications/spring-boot-upgrade/src/main/resources/static/css/button.css new file mode 100644 index 000000000..6fd587213 --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/static/css/button.css @@ -0,0 +1,233 @@ +button.recipeButton { + --html-font-size: 1em; + --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --font-weight: 400; + --monospace-font-family: "SFMono-Regular", "Consolas", "Liberation Mono", "Menlo", monospace; + --body-background-color: #fff; + --panel-background-color: #f6f8fa; + --panel-group-background-color: #e1e8e8; + --panel-border-color: #eaedf0; + --color-accent-1: #ebf2f2; + --color-accent-2: #d7e7e7; + --color-accent-3: #6db33f; + --body-font-color: #191e1e; + --body-font-light-color: #273030; + --body-font-dark-color: #141818; + --link-font-color: #1565c0; + --hover-link-font-color: #104d92; + --scrollbar-thumb-color: silver; + --mark-background-color: #39ff14; + --selected-background-color: #191e1e; + --layout-max-width: 1400px; + --layout-switchtheme-invert-filter: invert(); + --layout-switchtheme-background-color: var(--body-background-color); + --layout-switchtheme-button-color: var(--body-background-color); + --layout-switchtheme-button-hover-color: var(--color-accent-1); + --asciidoctor-doc-background-embellishment-height: 147px; + --asciidoctor-details-background: var(--color-accent-1); + --asciidoctor-details-font-color: var(--body-font-light-color); + --asciidoctor-author-separator-color: var(--color-accent-3); + --asciidoctor-panel-background: var(--panel-background-color); + --asciidoctor-panel-border-color: var(--panel-border-color); + --asciidoctor-font-color: var(--body-font-color); + --asciidoctor-heading-font-color: var(--body-font-dark-color); + --asciidoctor-heading-font-weight: 600; + --asciidoctor-alt-heading-font-weight: 600; + --asciidoctor-section-divider-color: var(--color-accent-1); + --asciidoctor-link-font-color: var(--link-font-color); + --asciidoctor-hover-link-font-color: var(--hover-link-font-color); + --asciidoctor-unresolved-link-font-color: #d32f2f; + --asciidoctor-code-font-color: var(--asciidoctor-font-color); + --asciidoctor-code-link-font-color: var(--link-font-color); + --asciidoctor-code-background: rgba(27, 31, 35, .05); + --asciidoctor-code-data-lang-color: #999; + --asciidoctor-table-border-color: var(--asciidoctor-panel-border-color); + --asciidoctor-table-header-footer-background: var(--color-accent-1); + --asciidoctor-table-stripe-background: var(--color-accent-1); + --asciidoctor-table-footer-background: linear-gradient(to bottom, var(--color-accent-1) 0%, var(--body-background-color) 100%); + --asciidoctor-admonition-background: var(--color-accent-1); + --asciidoctor-admonition-pre-background: var(--color-accent-2); + --asciidoctor-admonition-label-font-weight: 500; + --asciidoctor-admonition-font-color: #f0f0f0; + --asciidoctor-admonition-caution-background: #561164; + --asciidoctor-admonition-important-background: #960000; + --asciidoctor-admonition-note-background: #015785; + --asciidoctor-admonition-tip-background: #3e6b1f; + --asciidoctor-admonition-warning-background: #bd7400; + --asciidoctor-abstract-background: var(--asciidoctor-panel-background); + --asciidoctor-abstract-border-color: var(--asciidoctor-panel-border-color); + --asciidoctor-quote-background: var(--color-accent-1); + --asciidoctor-quote-border-color: var(--color-accent-3); + --asciidoctor-quote-attribution-font-color: var(--color-accent-3); + --asciidoctor-caption-font-color: var(--body-font-light-color); + --asciidoctor-caption-font-weight: 400; + --asciidoctor-example-background: var(--asciidoctor-panel-background); + --asciidoctor-example-border-color: var(--asciidoctor-panel-border-color); + --asciidoctor-sidebar-background: var(--color-accent-1); + --asciidoctor-pre-background: var(--asciidoctor-panel-background); + --asciidoctor-pre-border-color: var(--asciidoctor-panel-border-color); + --asciidoctor-callout-background: var(--body-font-dark-color); + --asciidoctor-callout-font-color: var(--body-background-color); + --asciidoctor-footer-font-color: #b6b6b6; + --highlight-background-color: var(--asciidoctor-pre-background); + --highlight-font-color: #24292e; + --highlight-keyword-font-color: #d73a49; + --highlight-comment-font-color: #6a737d; + --highlight-string-font-color: #032f62; + --highlight-meta-font-color: #6a737d; + --highlight-constant-font-color: #032f62; + --highlight-variable-font-color: #005cc5; + --highlight-tag-font-color: #22863a; + --highlight-tag-attribute-font-color: #6f42c1; + --highlight-type-font-color: #6f42c1; + --highlight-link-font-color: var(--link-font-color); + --highlight-addition-font-color: #22863a; + --highlight-deletion-font-color: #24292e; + --highlight-regex-font-color: #032f62; + --tabs-border-color: var(--selected-background-color); + --tabs-background-color: var(--body-background-color); + --tabs-font-color: var(--body-font-color); + --tabs-selected-background-color: var(--selected-background-color); + --tabs-selected-font-color: var(--body-background-color); + --tabs-hover-font-color: var(--hover-link-font-color); + --tabs-hover-background: var(--color-accent-1); + --tabs-group-background-color: var(--panel-group-background-color); + --toc-font-color: var(--body-font-color); + --toc-hover-background-color: var(--color-accent-1); + --toc-active-background-color: var(--selected-background-color); + --toc-active-font-color: var(--body-background-color); + --toc-back-to-index-filter: none; + --toc-bar-button-filter: none; + --codetools-button-filter: none; + --codetools-button-active-filter: invert(); + --codetools-background-color: var(--body-background-color); + --codetools-border-color: rgba(0, 0, 0, .3); + --codetools-hover-background-color: var(--color-accent-1); + --codetools-divider-color: var(--codetools-border-color); + --codetools-popup-background-color: var(--selected-background-color); + --codetools-popup-font-color: var(--body-background-color); + --layout-banner-height: 51px; + --layout-banner-logo-height: 30px; + --layout-banner-logo-offset: 10px; + --layout-border-color: var(--body-background-color); + --toc-bar-display: block; + --toc-bar-height: 24px; + --toc-width: 0; + --toc-display: none; + --asciidoctor-doc-embellishment-margin-width: 0; + --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; + overflow-wrap: anywhere; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + hyphens: none; + box-sizing: border-box; + margin: 0; + text-transform: none; + -webkit-appearance: button; + --bs-btn-padding-x: 0.75rem; + --bs-btn-padding-y: 0.375rem; + --bs-btn-font-size: 1rem; + --bs-btn-font-weight: 400; + --bs-btn-line-height: 1.5; + --bs-btn-border-width: 1px; + --bs-btn-border-radius: 0.375rem; + --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-size: var(--ebs-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; + 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 .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + --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; + cursor: pointer; +} \ No newline at end of file diff --git a/applications/rest-service/src/main/resources/static/css/site.css b/applications/spring-boot-upgrade/src/main/resources/static/css/site.css similarity index 100% rename from applications/rest-service/src/main/resources/static/css/site.css rename to applications/spring-boot-upgrade/src/main/resources/static/css/site.css diff --git a/applications/spring-boot-upgrade/src/main/resources/static/css/site.css.map b/applications/spring-boot-upgrade/src/main/resources/static/css/site.css.map new file mode 100755 index 000000000..689a2d1e3 --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/static/css/site.css.map @@ -0,0 +1,30 @@ +{ + "version": 3, + "sources": [ + "settings.css", + "settings-dark.css", + "generic.css", + "elements.css", + "layout.css", + "asciidoctor.css", + "highlight.css", + "tabs.css", + "toc.css", + "codetools.css" + ], + "names": [], + "mappings": ";;;;;AAgBA,MAIE,oBAAqB,CACrB,wBAAyB,CACzB,kJAEmB,CACnB,iBAAkB,CAClB,uFACoB,CACpB,4BAA8B,CAC9B,gCAAiC,CACjC,sCAAuC,CACvC,4BAA6B,CAC7B,wBAAyB,CACzB,wBAAyB,CACzB,wBAAyB,CACzB,yBAA0B,CAC1B,+BAAgC,CAChC,8BAA+B,CAC/B,yBAA0B,CAC1B,+BAAgC,CAChC,8BAA+B,CAC/B,+BAAgC,CAChC,mCAAoC,CAGpC,gCAAiC,CACjC,gCAAiC,CACjC,yBAA0B,CAC1B,2BAA4B,CAC5B,2CAA4C,CAC5C,2CAA4C,CAC5C,kEAAmE,CACnE,8DAA+D,CAC/D,6DAA8D,CAG9D,kDAAmD,CACnD,uDAAwD,CACxD,sDAAuD,CACvD,6DAA8D,CAC9D,0DAA2D,CAC3D,4DAA6D,CAC7D,0DAA2D,CAC3D,+CAAgD,CAChD,4DAA6D,CAC7D,qCAAsC,CACtC,yCAA0C,CAC1C,yDAA0D,CAC1D,oDAAqD,CACrD,gEAAiE,CACjE,gDAAiD,CACjD,2DAA4D,CAC5D,yDAA0D,CAC1D,gDAAqD,CACrD,uCAAwC,CACxC,sEAAuE,CACvE,kEAAmE,CACnE,2DAA4D,CAC5D,2HAIC,CACD,yDAA0D,CAC1D,6DAA8D,CAC9D,8CAA+C,CAC/C,2CAA4C,CAC5C,mDAAoD,CACpD,qDAAsD,CACtD,gDAAiD,CACjD,+CAAgD,CAChD,mDAAoD,CACpD,qEAAsE,CACtE,yEAA0E,CAC1E,oDAAqD,CACrD,sDAAuD,CACvD,gEAAiE,CACjE,6DAA8D,CAC9D,qCAAsC,CACtC,oEAAqE,CACrE,wEAAyE,CACzE,sDAAuD,CACvD,gEAAiE,CACjE,oEAAqE,CACrE,4DAA6D,CAC7D,6DAA8D,CAC9D,uCAAwC,CAGxC,8DAA+D,CAC/D,8BAA+B,CAC/B,sCAAuC,CACvC,sCAAuC,CACvC,qCAAsC,CACtC,mCAAoC,CACpC,uCAAwC,CACxC,uCAAwC,CACxC,kCAAmC,CACnC,4CAA6C,CAC7C,mCAAoC,CACpC,kDAAmD,CACnD,uCAAwC,CACxC,uCAAwC,CACxC,oCAAqC,CAGrC,oDAAqD,CACrD,oDAAqD,CACrD,wCAAyC,CACzC,iEAAkE,CAClE,uDAAwD,CACxD,oDAAqD,CACrD,6CAA8C,CAC9C,iEAAkE,CAGlE,iBAAkB,CAClB,mBAAoB,CACpB,uCAAwC,CACxC,kDAAmD,CACnD,8DAA+D,CAC/D,oDAAqD,CACrD,+BAAgC,CAChC,sBAAuB,CACvB,kBAAmB,CACnB,4BAA6B,CAG7B,8BAA+B,CAC/B,yCAA0C,CAC1C,yDAA0D,CAC1D,uCAA4C,CAC5C,wDAAyD,CACzD,uDAAwD,CACxD,mEAAoE,CACpE,yDACF,CAIA,qCACE,MACE,iBAAkB,CAClB,kDACF,CACF,CAEA,oCACE,MACE,2BAA4B,CAC5B,gCAAiC,CACjC,gCAAiC,CACjC,kDAAmD,CACnD,uBAAwB,CACxB,qBAAsB,CACtB,aAAc,CACd,kBAAmB,CACnB,8CACF,CACF,CCnLA,gBAEE,iBAAkB,CAClB,+BAAgC,CAChC,gCAAiC,CACjC,sCAAuC,CACvC,4BAA6B,CAC7B,wBAAyB,CACzB,+BAAgC,CAChC,wBAAyB,CACzB,wBAAyB,CACzB,yBAA0B,CAC1B,+BAAgC,CAChC,8BAA+B,CAC/B,yBAA0B,CAC1B,+BAAgC,CAChC,+BAAgC,CAChC,+BAAgC,CAChC,mCAAoC,CAGpC,uCAAwC,CACxC,sEAAuE,CAGvE,mDAAwD,CACxD,0CAA2C,CAC3C,2CAA4C,CAC5C,mDAAoD,CACpD,qDAAsD,CACtD,gDAAiD,CACjD,+CAAgD,CAChD,mDAAoD,CACpD,uCAAwC,CAGxC,8DAA+D,CAC/D,8BAA+B,CAC/B,sCAAuC,CACvC,sCAAuC,CACvC,qCAAsC,CACtC,mCAAoC,CACpC,uCAAwC,CACxC,uCAAwC,CACxC,kCAAmC,CACnC,4CAA6C,CAC7C,mCAAoC,CACpC,mCAAoC,CACpC,uCAAwC,CACxC,uCAAwC,CACxC,oCAAqC,CAGrC,mCAAoC,CACpC,gCAAiC,CAGjC,kCAAmC,CACnC,qCAAsC,CACtC,+DAAgE,CAChE,6CAAoD,CACpD,6CACF,CC9CA,KACE,qBACF,CAEA,iBAGE,kBACF,CAEA,KACE,6BAAsB,CAAtB,0BAAsB,CAAtB,qBACF,CCZA,KAEE,+BAAgC,CADhC,WAAY,CAGZ,eAAgB,CADhB,sBAEF,CAEA,KAOE,6CAA8C,CAD9C,4BAA6B,CAF7B,8BAA+B,CAC/B,8BAA+B,CAJ/B,QAAS,CACT,sBAAuB,CACvB,wBAAyB,CAAzB,wBAKF,CAEA,EACE,oBACF,CAEA,QACE,yBACF,CAEA,SACE,qBACF,CAEA,aAGE,wCACF,CAEA,iCACE,OAEE,wDAAyD,CADzD,oBAEF,CACF,CAEA,MAEE,gBAAiB,CADjB,wBAEF,CAEA,KACE,uCACF,CCjDA,kBAGE,kDAAmD,CAFnD,kCAAmC,CACnC,eAEF,CAEA,QAEE,sIAC0E,CAC1E,4CAA+C,CAH/C,WAIF,CAEA,KACE,aACF,CAEA,WAEE,aAAc,CADd,iCAEF,CAEA,qCAEE,YACF,CAEA,yBACE,aAAc,CACd,WAAY,CACZ,kBACF,CAEA,oBACE,uBAAgB,CAAhB,oBAAgB,CAAhB,eAAgB,CAKhB,6IAEuE,CACvE,2DAA4D,CAL5D,WAAY,CAOZ,YAAa,CATb,iBAAkB,CAClB,UASF,CAEA,+CAJE,kBAAmB,CALnB,8CAoBF,CAXA,2BASE,uDAAwD,CAPxD,UAAW,CAIX,WAAY,CAFZ,QAAS,CADT,iBAAkB,CAElB,OAAQ,CAKR,wBAA2B,CAH3B,UAIF,CAEA,iCACE,6DACF,CAEA,mCACE,0BACF,CCxEA,KACE,mCAAoC,CACpC,oBAAa,CAAb,gBAAa,CAAb,YAAa,CAEb,8BAAgC,CADhC,eAAgB,CAEhB,QACF,CAIA,2BAEE,aACF,CAEA,wBAEE,gBAAiB,CACjB,iBACF,CAEA,cACE,mBACF,CAIA,KACE,uCAA6C,CAC7C,+CACF,CAEA,aACE,8DACF,CAIA,sBACE,gDAAiD,CACjD,2CAA4C,CAG5C,cAAgB,CADhB,eAAgB,CADhB,mBAGF,CAEA,yBACE,YAAa,CACb,cACF,CAEA,oBACE,YACF,CAEA,2DAIE,+CAAgD,CAHhD,eAAgB,CAChB,eAAgB,CAChB,WAEF,CAEA,6CACE,YACF,CAEA,iCACE,eAAgB,CAGhB,eAAgB,CAFhB,gBAAkB,CAClB,yBAEF,CAIA,yCAEE,eACF,CAEA,mBACE,6DACF,CAIA,QACE,eACF,CAEA,QACE,aACF,CAEA,QACE,eACF,CAEA,QACE,eACF,CAEA,QACE,eACF,CAEA,QACE,eACF,CAEA,gDAME,2CAA4C,CAC5C,kDAAmD,CACnD,oBAAa,CAAb,gBAAa,CAAb,YAAa,CACb,eAAgB,CAChB,iBAAkB,CAClB,kBACF,CAEA,cACE,iDAAkD,CAClD,eAAgB,CAChB,qBAAsB,CACtB,kBACF,CAEA,oBACE,eACF,CAEA,uBACE,iBAAkB,CAClB,kBAAmB,CACnB,yBACF,CAEA,uBACE,sDACF,CAIA,gGAYE,eAAmB,CAHnB,gBAAiB,CACjB,iBAAmB,CAJnB,iBAAkB,CAClB,oBAAqB,CAIrB,iBAAkB,CAHlB,YAKF,CAEA,0IAME,eACF,CAEA,oIAME,kBACF,CAEA,eAEE,QACF,CAIA,YACE,oBAAa,CAAb,gBAAa,CAAb,YACF,CAEA,OACE,wCACF,CAEA,aACE,8CACF,CAEA,kBACE,mDACF,CAIA,uDAIE,6CAA8C,CAC9C,mBAAqB,CAFrB,wCAAyC,CAGzC,eAAiB,CACjB,oBACF,CAEA,6DAGE,6CACF,CAEA,mBAEE,oBAAa,CAAb,gBAAa,CAAb,YACF,CAEA,SACE,sCAAyC,CACzC,eAAgB,CAChB,QACF,CAEA,sFAGE,4CAA6C,CAK7C,iBAAkB,CAJlB,+DAAgE,CAChE,aAAc,CACd,eAAgB,CAChB,cAEF,CAEA,0CASE,6CAA8C,CAR9C,uBAAwB,CAExB,aAAc,CAKd,eAAiB,CADjB,aAAc,CAHd,iBAAkB,CAElB,WAAa,CAJb,wBAAyB,CAGzB,SAKF,CAEA,mBACE,iBACF,CAEA,gDACE,YACF,CAIA,gBACE,QACF,CAEA,uBACE,sCACF,CAEA,qOAeE,eACF,CAIA,sBACE,aAAc,CAEd,eAAgB,CADhB,UAEF,CAEA,yBACE,cACF,CAEA,sBACE,sCAAyC,CACzC,iBACF,CAEA,wBACE,eACF,CAEA,yCACE,YACF,CAEA,kDAEE,aACF,CAEA,+BACE,+DACF,CAEA,8DAGE,6DAA8D,CAD9D,0DAEF,CAEA,0KAIE,qDACF,CAEA,4BACE,qDACF,CAEA,uEAGE,oBACF,CAEA,oHAGE,kBACF,CAIA,sBACE,eACF,CAEA,yDAEE,sCACF,CAEA,oGAEE,YACF,CAEA,0BAEE,WAAY,CADZ,sCAEF,CAEA,4BAEE,iBAAkB,CADlB,kBAAmB,CAEnB,UACF,CAEA,iCAIE,kBAAmB,CAFnB,mDAAoD,CADpD,wBAA0B,CAE1B,UAEF,CAEA,8BAOE,oBAAsB,CAHtB,sCAAyC,CADzC,MAAO,CAEP,aAAc,CAGd,oBAAuB,CAPvB,iBAAkB,CAClB,KAAM,CAIN,gCAGF,CAEA,8BAEE,kBAAmB,CAInB,0BAA4B,CAD5B,2BAA4B,CAJ5B,mBAAoB,CAMpB,mBAAoB,CAHpB,WAAY,CAIZ,gBAAiB,CACjB,sBAAuB,CANvB,UAOF,CAEA,oCACE,wCAA+C,CAK/C,8CAA+C,CAJ/C,mBAAoB,CAEpB,mBAAoB,CAGpB,iBAAkB,CAFlB,2DAA4D,CAG5D,oBAAa,CAAb,gBAAa,CAAb,YAAa,CAEb,aAAe,CADf,cAAgB,CANhB,yBAQF,CAEA,KACE,yBACF,CAEA,kBACE,uDACF,CAEA,oBACE,sDACF,CAEA,eACE,sDACF,CAEA,cACE,4DACF,CAEA,kBACE,uDACF,CAEA,sCACE,2DACF,CAEA,wCACE,6DACF,CAEA,iCACE,wDACF,CAEA,gCACE,uDACF,CAEA,oCACE,iEACF,CAIA,iBAGE,kBAAmB,CAFnB,YAAa,CACb,qBAEF,CAEA,qCAEE,oBAAqB,CACrB,WAAY,CACZ,cAAe,CACf,qBACF,CAEA,uCACE,gBACF,CAIA,oCACE,iDAAkD,CAClD,8DAA+D,CAC/D,sCAAyC,CACzC,iBACF,CAEA,kCAEE,8CAA+C,CAC/C,2DACF,CAEA,iBACE,2BACF,CAEA,8BACE,qDAAsD,CACtD,sCAAyC,CACzC,iBACF,CAEA,4BACE,eACF,CAEA,4BACE,iBACF,CAEA,sBACE,gBACF,CAIA,iBACE,gBAAiB,CACjB,iBACF,CAEA,qBACE,mBAAoB,CACpB,iBACF,CAIA,gBAEE,QAAS,CACT,kBACF,CAEA,mHAOE,oBACF,CAEA,qCAEE,oBACF,CAEA,kCAEE,cACF,CAUA,2CACE,sBACF,CAEA,eACE,uBACF,CAEA,gBACE,oCACF,CAEA,mBACE,2BACF,CAEA,mBACE,2BACF,CAEA,mBACE,2BACF,CAEA,mBACE,2BACF,CAEA,mBACE,2BACF,CAEA,kBACE,kBACF,CAEA,kGAEE,mBAAoB,CACpB,sBAAuB,CACvB,aACF,CAEA,6CACE,eACF,CAEA,uCACE,eACF,CAEA,2KASE,gBACF,CAEA,8BAEE,mBACF,CAEA,wFAGE,SACF,CAIA,mLAOE,2CAA4C,CAC5C,sCAAyC,CAEzC,iBAAkB,CADlB,kDAAmD,CAEnD,oBAAa,CAAb,gBAAa,CAAb,YAAa,CACb,oBAAsB,CACtB,sBAAwB,CACxB,eACF,CAEA,wBACE,gBAAkB,CAClB,gBACF,CAIA,4BACE,gDAAiD,CACjD,wDAAyD,CACzD,iBAAkB,CAClB,cACF,CAEA,yCACE,YACF,CAIA,mBACE,gDAAiD,CACjD,cACF,CAEA,mCACE,sCAAyC,CACzC,sDAAuD,CACvD,eAAgB,CAChB,oBACF,CAEA,qDACE,YACF,CAIA,cACE,kBACF,CAEA,qBACE,WAAY,CACZ,mBACF,CAEA,oBACE,WAAY,CACZ,kBACF,CAIA,yBAEE,oBAAa,CAAb,gBAAa,CAAb,YACF,CAEA,6BACE,eAAgB,CAChB,eAAgB,CAChB,oDAAqD,CACrD,kBACF,CAIA,SAGE,4CAA6C,CAC7C,oDAAqD,CACrD,mBAAqB,CACrB,8FAC0C,CAN1C,oBAAqB,CACrB,sCAAyC,CAMzC,kBAAqB,CACrB,0BAA2B,CAC3B,kBACF,CAEA,sBAEE,aACF,CAEA,aACE,sCACF,CAEA,iBACE,eACF,CAEA,6BACE,aACF,CAEA,4BACE,cACF,CAIA,UAEE,iBAAkB,CADlB,oBAAa,CAAb,gBAAa,CAAb,YAEF,CAEA,kCACE,wBAAiB,CAAjB,qBAAiB,CAAjB,oBAAiB,CAAjB,gBACF,CAEA,eACE,iBACF,CAEA,eACE,wBACF,CAEA,4BACE,eACF,CAEA,gCAEE,iBAAmB,CACnB,kBACF,CAEA,0DAEE,aACF,CAEA,gBACE,wCAAyC,CACzC,oBACF,CAEA,gBACE,mBACF,CAEA,aACE,sCAAyC,CACzC,uBACF,CAEA,4EAEE,qBAAwB,CACxB,kBACF,CAEA,0EAEE,gBACF,CAEA,wBAaE,gDAAiD,CAVjD,kBAAmB,CAWnB,2CAA4C,CAV5C,oBAAqB,CAFrB,wCAAyC,CAGzC,wCAA2C,CAC3C,iBAAkB,CAIlB,aAAc,CACd,qBAAuB,CAJvB,eAAgB,CAChB,iBAAkB,CAIlB,kBAAoB,CAHpB,YAMF,CAEA,8BACE,wBACF,CAEA,0BACE,YACF,CAEA,QACE,qDAAsD,CACtD,oBAAqB,CACrB,QACF,CAIA,sBACE,kBACF,CAEA,cAEE,gBAAiB,CADjB,oBAAa,CAAb,gBAAa,CAAb,YAEF,CAEA,YACE,WACF,CAEA,WACE,UACF,CAEA,cACE,UACF,CAEA,gBACE,yBACF,CAEA,mBACE,4BACF,CAEA,kBACE,eACF,CAEA,mBACE,gBACF,CAEA,oBACE,iBACF,CAEA,iBACE,kBACF,CAEA,oBACE,qBACF,CAEA,oBACE,qBACF,CAIA,qBAIE,6DAA8D,CAF9D,0CAA2C,CAD3C,sCAAyC,CAEzC,cAEF,CAIA,qBACE,uCAA6C,CAC7C,oDACF,CAEA,qCACE,KACE,sCAA4C,CAC5C,+CACF,CACA,qBACE,sCAA4C,CAC5C,oDACF,CACF,CAEA,oCACE,0BAEE,eACF,CACF,CC36BA,MAIE,4CAA6C,CAC7C,iCAAkC,CAJlC,aAAc,CACd,eAAgB,CAChB,YAGF,CAEA,6CAGE,yCACF,CAEA,0BAEE,yCACF,CAEA,0BAEE,wCACF,CAEA,WACE,sCACF,CAEA,0EAKE,0CACF,CAEA,uCAEE,0CACF,CAEA,qCAGE,qCACF,CAEA,qBACE,+CACF,CAEA,mCAEE,sCACF,CAEA,aACE,uCACF,CAEA,WAEE,sCAAuC,CADvC,yBAEF,CAEA,eACE,0CACF,CAEA,eACE,0CACF,CAEA,eACE,iBACF,CAEA,aACE,eACF,CAEA,yDAEE,0CACF,CAEA,0BACE,wCACF,CCtFA,QACE,YACF,CAEA,WAGE,iBAAkB,CAGlB,QAAS,CAFT,oBAAqB,CAFrB,sCAAyC,CADzC,eAAiB,CAOjB,yCAA4C,CAD5C,gBAAkB,CAFlB,iBAIF,CAMA,sCAHE,yCAaF,CAVA,UAEE,6CAA8C,CAM9C,eAAgB,CALhB,4BAA6B,CAE7B,cAAe,CADf,oBAAqB,CAGrB,yCAA4C,CAN5C,mBAAsB,CAQtB,+BACF,CAEA,gBAEE,6CAA8C,CAD9C,kCAAmC,CAEnC,yBACF,CAEA,mBACE,sDAAuD,CACvD,kDAAmD,CACnD,qCACF,CAEA,yBACE,qCAAsC,CACtC,oBACF,CAEA,yCAEE,mDAAoD,CADpD,YAEF,CCrDA,mBACE,gDAAiD,CAEjD,4BAA6B,CAD7B,aAEF,CAEA,KAME,iDAAkD,CALlD,0BAA2B,CAO3B,gBAAkB,CAClB,eAAgB,CAJhB,qCAAwC,CAExC,qBAA2B,CAL3B,iBAAkB,CAClB,+BAAgC,CAChC,sBAMF,CAEA,UACE,YACF,CAEA,gBAEE,SACF,CAEA,sBAEE,kBACF,CAEA,QACE,aAAc,CACd,eACF,CAEA,OAKE,iBAAkB,CAFlB,2BAA4B,CAF5B,aAAc,CAGd,mBAAsB,CAFtB,oBAIF,CAEA,aACE,kDACF,CAEA,oBAIE,WAAY,CADZ,iBAAkB,CAFlB,cAAe,CACf,KAGF,CAEA,iBACE,mDAAoD,CACpD,kCACF,CAEA,sBAEE,YACF,CAEA,sEAIE,aACF,CAEA,eACE,aAAc,CACd,mBACF,CAEA,iBAEE,mBAAqB,CACrB,iBAAmB,CAFnB,mBAGF,CAEA,wBAGE,kCAAwC,CACxC,8DAAiE,CAHjE,UAAW,CAIX,aAAc,CAHd,sCAAuC,CAOvC,WAAY,CADZ,eAAgB,CADhB,cAAe,CADf,iBAIF,CAEA,kBAOE,6CAA8C,CAC9C,iDAAkD,CAPlD,8BAA+B,CAK/B,2BAA4B,CAJ5B,UAAW,CAOX,aANF,CASA,QAEE,WAAY,CACZ,gBAAiB,CAFjB,UAGF,CAEA,iCACE,cAAe,CACf,KACF,CAEA,kBAIE,kCAAwC,CACxC,4DAA+D,CAC/D,WAAY,CAGZ,aAAc,CANd,mCAAoC,CADpC,4BAA6B,CAK7B,YAAa,CACb,SAAU,CAPV,2BASF,CAEA,gCACE,mDACF,CAEA,oCACE,oBACE,yBACF,CAEA,KAKE,6CAA8C,CAF9C,WAAY,CACZ,MAAO,CAHP,6DAA8D,CAC9D,UAAW,CAIX,aACF,CAEA,mBACE,aACF,CACF,CCxJA,cACE,mBAAoB,CACpB,oBAAqB,CACrB,gBAAiB,CAKjB,4CAA6C,CAG7C,8CAA+C,CAD/C,iBAAkB,CAJlB,UAAW,CAFX,YAAa,CAQb,SAAU,CAHV,SAAU,CAJV,iBAAkB,CAElB,SAAU,CAMV,mCACF,CAEA,uCACE,SACF,CAEA,qBAIE,kCAAwC,CACxC,WAAY,CAFZ,qCAAsC,CADtC,2BAA4B,CAK5B,YAAa,CADb,SAAU,CALV,yBAOF,CAEA,sCACE,qDACF,CAEA,2BACE,wDAAyD,CACzD,qBACF,CAEA,4BACE,4CAA6C,CAC7C,sBACF,CAEA,gCACE,YACF,CAEA,iCACE,wDACF,CAEA,mCACE,wDACF,CAEA,iCACE,sDACF,CAEA,0BAGE,UAAW,CADX,aAAc,CAId,2BAA4B,CAL5B,SAAU,CAGV,iBAAkB,CAIlB,sBAAyB,CAHzB,yBAA0B,CAE1B,eAEF,CAEA,wCACE,eAAgB,CAChB,sBACF,CAEA,iCAME,sEAAuE,CACvE,2DACa,CADb,6BACa,CADb,8BACa,CADb,4BACa,CANb,iCAAoC,CAGpC,UAAW,CAFX,QAAS,CACT,sCAAyC,CAHzC,iBAQF,CAEA,gCAME,wDAAyD,CAGzD,iBAAkB,CAFlB,uCAAwC,CANxC,8BAA+B,CAS/B,eAAiB,CALjB,yCAA4C,CAG5C,eAAgB,CANhB,iBAAkB,CAElB,UAAW,CADX,kDAQF,CAEA,yCACE,SACF,CAEA,gBAGE,UAAW,CADX,UAAW,CAGX,eAAgB,CADhB,oBAAsB,CAHtB,iBAKF,CAEA,sGAEE,kBAAmB,CACnB,SACF,CAEA,sGAEE,YAAe,CACf,SACF,CAEA,gDACE,gBAAiB,CACjB,SACF,CAEA,gDACE,gBAAiB,CACjB,SACF,CAEA,gGAEE,YAAa,CACb,SACF,CAEA,kDACE,kEACF,CAMA,gGACE,kEACF,CAEA,8CACE,kEACF", + "file": "site.css", + "sourcesContent": [ + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n:root {\n /* NOTE: Don't use relative `url()` values in here. Safari load them properly */\n\n /* General */\n --html-font-size: 1em;\n --pixel-to-rem: 16 * 1rem;\n --font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\",\n \"Segoe UI Symbol\";\n --font-weight: 400;\n --monospace-font-family: \"SFMono-Regular\", \"Consolas\", \"Liberation Mono\",\n \"Menlo\", monospace;\n --body-background-color: white;\n --panel-background-color: #f6f8fa;\n --panel-group-background-color: #e1e8e8;\n --panel-border-color: #eaedf0;\n --color-accent-1: #ebf2f2;\n --color-accent-2: #d7e7e7;\n --color-accent-3: #6db33f;\n --body-font-color: #191e1e;\n --body-font-light-color: #273030;\n --body-font-dark-color: #141818;\n --link-font-color: #1565c0;\n --hover-link-font-color: #104d92;\n --scrollbar-thumb-color: silver;\n --mark-background-color: #39ff14;\n --selected-background-color: #191e1e;\n\n /* Layout */\n --layout-banner-logo-offset: 18px;\n --layout-banner-logo-height: 50px;\n --layout-max-width: 1400px;\n --layout-banner-height: 80px;\n --layout-border-color: var(--color-accent-1);\n --layout-switchtheme-invert-filter: invert();\n --layout-switchtheme-background-color: var(--body-background-color);\n --layout-switchtheme-button-color: var(--body-background-color);\n --layout-switchtheme-button-hover-color: var(--color-accent-1);\n\n /* Asciidoctor */\n --asciidoctor-doc-embellishment-margin-width: 250px;\n --asciidoctor-doc-background-embellishment-height: 147px;\n --asciidoctor-details-background: var(--color-accent-1);\n --asciidoctor-details-font-color: var(--body-font-light-color);\n --asciidoctor-author-separator-color: var(--color-accent-3);\n --asciidoctor-panel-background: var(--panel-background-color);\n --asciidoctor-panel-border-color: var(--panel-border-color);\n --asciidoctor-font-color: var(--body-font-color);\n --asciidoctor-heading-font-color: var(--body-font-dark-color);\n --asciidoctor-heading-font-weight: 600;\n --asciidoctor-alt-heading-font-weight: 600;\n --asciidoctor-section-divider-color: var(--color-accent-1);\n --asciidoctor-link-font-color: var(--link-font-color);\n --asciidoctor-hover-link-font-color: var(--hover-link-font-color);\n --asciidoctor-unresolved-link-font-color: #d32f2f;\n --asciidoctor-code-font-color: var(--asciidoctor-font-color);\n --asciidoctor-code-link-font-color: var(--link-font-color);\n --asciidoctor-code-background: rgba(27, 31, 35, 0.05);\n --asciidoctor-code-data-lang-color: #999;\n --asciidoctor-table-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-table-header-footer-background: var(--color-accent-1);\n --asciidoctor-table-stripe-background: var(--color-accent-1);\n --asciidoctor-table-footer-background: linear-gradient(\n to bottom,\n var(--color-accent-1) 0%,\n var(--body-background-color) 100%\n );\n --asciidoctor-admonition-background: var(--color-accent-1);\n --asciidoctor-admonition-pre-background: var(--color-accent-2);\n --asciidoctor-admonition-label-font-weight: 500;\n --asciidoctor-admonition-font-color: #f0f0f0;\n --asciidoctor-admonition-caution-background: #561164;\n --asciidoctor-admonition-important-background: #960000;\n --asciidoctor-admonition-note-background: #015785;\n --asciidoctor-admonition-tip-background: #3e6b1f;\n --asciidoctor-admonition-warning-background: #bd7400;\n --asciidoctor-abstract-background: var(--asciidoctor-panel-background);\n --asciidoctor-abstract-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-quote-background: var(--color-accent-1);\n --asciidoctor-quote-border-color: var(--color-accent-3);\n --asciidoctor-quote-attribution-font-color: var(--color-accent-3);\n --asciidoctor-caption-font-color: var(--body-font-light-color);\n --asciidoctor-caption-font-weight: 400;\n --asciidoctor-example-background: var(--asciidoctor-panel-background);\n --asciidoctor-example-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-sidebar-background: var(--color-accent-1);\n --asciidoctor-pre-background: var(--asciidoctor-panel-background);\n --asciidoctor-pre-border-color: var(--asciidoctor-panel-border-color);\n --asciidoctor-callout-background: var(--body-font-dark-color);\n --asciidoctor-callout-font-color: var(--body-background-color);\n --asciidoctor-footer-font-color: #b6b6b6;\n\n /* Highlight JS (colors based on https://github.com/primer/github-syntax-light) */\n --highlight-background-color: var(--asciidoctor-pre-background);\n --highlight-font-color: #24292e;\n --highlight-keyword-font-color: #d73a49;\n --highlight-comment-font-color: #6a737d;\n --highlight-string-font-color: #032f62;\n --highlight-meta-font-color: #6a737d;\n --highlight-constant-font-color: #032f62;\n --highlight-variable-font-color: #005cc5;\n --highlight-tag-font-color: #22863a;\n --highlight-tag-attribute-font-color: #6f42c1;\n --highlight-type-font-color: #6f42c1;\n --highlight-link-font-color: var(--link-font-color);\n --highlight-addition-font-color: #22863a;\n --highlight-deletion-font-color: #24292e;\n --highlight-regex-font-color: #032f62;\n\n /* Tabs */\n --tabs-border-color: var(--selected-background-color);\n --tabs-background-color: var(--body-background-color);\n --tabs-font-color: var(--body-font-color);\n --tabs-selected-background-color: var(--selected-background-color);\n --tabs-selected-font-color: var(--body-background-color);\n --tabs-hover-font-color: var(--hover-link-font-color);\n --tabs-hover-background: var(--color-accent-1);\n --tabs-group-background-color: var(--panel-group-background-color);\n\n /* TOC */\n --toc-width: 24rem;\n --toc-display: block;\n --toc-font-color: var(--body-font-color);\n --toc-hover-background-color: var(--color-accent-1);\n --toc-active-background-color: var(--selected-background-color);\n --toc-active-font-color: var(--body-background-color);\n --toc-back-to-index-filter: none;\n --toc-bar-display: none;\n --toc-bar-height: 0;\n --toc-bar-button-filter: none;\n\n /* Code Tools */\n --codetools-button-filter: none;\n --codetools-button-active-filter: invert();\n --codetools-background-color: var(--body-background-color);\n --codetools-border-color: rgba(0, 0, 0, 0.3);\n --codetools-hover-background-color: var(--color-accent-1);\n --codetools-divider-color: var(--codetools-border-color);\n --codetools-popup-background-color: var(--selected-background-color);\n --codetools-popup-font-color: var(--body-background-color);\n}\n\n/* Responsive Overrides */\n\n@media screen and (max-width: 1024px) {\n :root {\n --toc-width: 16rem;\n --asciidoctor-doc-embellishment-margin-width: 140px;\n }\n}\n\n@media screen and (max-width: 800px) {\n :root {\n --layout-banner-height: 51px;\n --layout-banner-logo-height: 30px;\n --layout-banner-logo-offset: 10px;\n --layout-border-color: var(--body-background-color);\n --toc-bar-display: block;\n --toc-bar-height: 24px;\n --toc-width: 0;\n --toc-display: none;\n --asciidoctor-doc-embellishment-margin-width: 0;\n }\n}\n", + "html.dark-theme {\n /* General */\n --font-weight: 300;\n --body-background-color: #1b1f23;\n --panel-background-color: #262a2d;\n --panel-group-background-color: #303741;\n --panel-border-color: #2c3135;\n --color-accent-1: #272c33;\n --color-accent-1-invert: #d8d3cc;\n --color-accent-2: #2d333a;\n --color-accent-3: #6db33f;\n --body-font-color: #bbbcbe;\n --body-font-light-color: #abacaf;\n --body-font-dark-color: #cecfd1;\n --link-font-color: #086dc3;\n --hover-link-font-color: #107ddd;\n --scrollbar-thumb-color: #5f5f5f;\n --mark-background-color: #2eca12;\n --selected-background-color: #8d8d8d;\n\n /* Layout */\n --layout-switchtheme-invert-filter: none;\n --layout-switchtheme-background-color: var(--selected-background-color);\n\n /* Asciidoctor */\n --asciidoctor-code-background: rgba(177, 209, 241, 0.15);\n --asciidoctor-code-data-lang-color: #6e6e6e;\n --asciidoctor-admonition-font-color: #f0f0f0;\n --asciidoctor-admonition-caution-background: #603668;\n --asciidoctor-admonition-important-background: #924040;\n --asciidoctor-admonition-note-background: #355463;\n --asciidoctor-admonition-tip-background: #4d6340;\n --asciidoctor-admonition-warning-background: #967745;\n --asciidoctor-footer-font-color: #5e5e5e;\n\n /* Highlight JS (colors based on https://github.com/primer/github-syntax-dark) */\n --highlight-background-color: var(--asciidoctor-pre-background);\n --highlight-font-color: #f6f8fa;\n --highlight-keyword-font-color: #ea4a5a;\n --highlight-comment-font-color: #959da5;\n --highlight-string-font-color: #79b8ff;\n --highlight-meta-font-color: #959da5;\n --highlight-constant-font-color: #79b8ff;\n --highlight-variable-font-color: #c8e1ff;\n --highlight-tag-font-color: #7bcc72;\n --highlight-tag-attribute-font-color: #b392f0;\n --highlight-type-font-color: #b392f0;\n --highlight-link-font-color: #1565c0;\n --highlight-addition-font-color: #7bcc72;\n --highlight-deletion-font-color: #f6f8fa;\n --highlight-regex-font-color: #79b8ff;\n\n /* TOC */\n --toc-back-to-index-filter: invert();\n --toc-bar-button-filter: invert();\n\n /* Code Tools */\n --codetools-button-filter: invert();\n --codetools-button-active-filter: none;\n --codetools-hover-background-color: var(--color-accent-1-invert);\n --codetools-border-color: rgba(255, 255, 255, 0.274);\n --codetools-divider-color: rgba(44, 44, 44, 0.274);\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nhtml {\n box-sizing: border-box;\n}\n\n*,\n*:before,\n*:after {\n box-sizing: inherit;\n}\n\nbody {\n text-size-adjust: none;\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nhtml {\n height: 100%;\n font-size: var(--html-font-size);\n scroll-behavior: smooth;\n min-width: 340px;\n}\n\nbody {\n margin: 0;\n overflow-wrap: anywhere;\n overscroll-behavior: none;\n font-family: var(--font-family);\n font-weight: var(--font-weight);\n color: var(--body-font-color);\n background-color: var(--body-background-color);\n}\n\na {\n text-decoration: none;\n}\n\na:hover {\n text-decoration: underline;\n}\n\na:active {\n background-color: none;\n}\n\ncode,\nkbd,\npre {\n font-family: var(--monospace-font-family);\n}\n\n@supports (scrollbar-width: thin) {\n body * {\n scrollbar-width: thin;\n scrollbar-color: var(--scrollbar-thumb-color) transparent;\n }\n}\n\ntable {\n border-collapse: collapse;\n word-wrap: normal;\n}\n\nmark {\n background: var(--mark-background-color);\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n#banner-container {\n height: var(--layout-banner-height);\n overflow: hidden;\n border-bottom: 1px solid var(--layout-border-color);\n}\n\n#banner {\n height: 100%;\n background: no-repeat top var(--layout-banner-logo-offset) left\n var(--layout-banner-logo-offset) / auto var(--layout-banner-logo-height);\n background-image: url(\"../img/banner-logo.svg\");\n}\n\n#doc {\n overflow: auto;\n}\n\n.contained {\n max-width: var(--layout-max-width);\n margin: 0 auto;\n}\n\ndiv#switch-theme,\n#switch-theme label {\n display: none;\n}\n\nhtml.js div#switch-theme {\n display: block;\n float: right;\n margin: 8px 6px 0 0;\n}\n\n#switch-theme input {\n appearance: none;\n position: relative;\n width: 40px;\n height: 22px;\n filter: var(--layout-switchtheme-invert-filter);\n background: no-repeat url(\"../img/octicons-16.svg#view-sun\") 90% 50% / 16px\n 16px,\n no-repeat url(\"../img/octicons-16.svg#view-moon\") 10% 50% / 16px 16px;\n background-color: var(--layout-switchtheme-background-color);\n border-radius: 25px;\n outline: none;\n}\n\n#switch-theme input::before {\n filter: var(--layout-switchtheme-invert-filter);\n content: \"\";\n position: absolute;\n left: 2px;\n top: 2px;\n height: 18px;\n width: 18px;\n border-radius: 25px;\n background-color: var(--layout-switchtheme-button-color);\n transition: transform 200ms;\n}\n\n#switch-theme:hover input::before {\n background-color: var(--layout-switchtheme-button-hover-color);\n}\n\n#switch-theme input:checked::before {\n transform: translateX(18px);\n}\n", + "/*\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n\n/* Asciidoctor styling based on https://gitlab.com/antora/antora-ui-default/-/blob/8751b86b76d6779fbbcf0fccd58fafcf73c49260/src/css/doc.css */\n\n/* Container element styling */\n\n.doc {\n color: var(--asciidoctor-font-color);\n hyphens: none;\n line-height: 1.6;\n letter-spacing: -0.0027777778rem;\n margin: 0;\n}\n\n/* Gutter and margins */\n\n.doc #content,\n.doc #footer {\n margin: 0 2rem;\n}\n\n.doc #header > *:not(#toc) {\n /* Gutter is not applied directly to #header of toc positioning */\n margin-left: 2rem;\n margin-right: 2rem;\n}\n\n.doc #content {\n padding-bottom: 4rem;\n}\n\n/* Doc background embellishment */\n\n#doc {\n background: no-repeat top right / 305px 147px;\n background-image: url(\"../img/doc-background.svg\");\n}\n\n.doc #header {\n margin-right: var(--asciidoctor-doc-embellishment-margin-width);\n}\n\n/* Header Details */\n\n.doc #header .details {\n background: var(--asciidoctor-details-background);\n color: var(--asciidoctor-details-font-color);\n padding: 1rem 1.5rem;\n font-weight: 600;\n font-size: 0.8em;\n}\n\n.doc #header div.details {\n display: flex;\n flex-wrap: wrap;\n}\n\n#header .details br {\n display: none;\n}\n\n.doc #header .details span.author:not(:last-of-type)::after {\n content: \"\\2022\";\n font-weight: 400;\n margin: 0.4em;\n color: var(--asciidoctor-author-separator-color);\n}\n\n.doc #header .details span.last-author::after {\n display: none;\n}\n\n.doc #header .details #revnumber {\n flex-basis: 100%;\n margin-top: 0.5rem;\n text-transform: capitalize;\n font-weight: 200;\n}\n\n/* Section setup */\n\n.doc #preamble + .sect1,\n.doc .sect1 + .sect1 {\n margin-top: 2rem;\n}\n\n.doc .sect1 + .sect1 {\n border-top: 1px solid var(--asciidoctor-section-divider-color);\n}\n\n/* Headings */\n\n.doc h1 {\n font-size: 2.3em;\n}\n\n.doc h2 {\n font-size: 2em;\n}\n\n.doc h3 {\n font-size: 1.7em;\n}\n\n.doc h4 {\n font-size: 1.6em;\n}\n\n.doc h5 {\n font-size: 1.4em;\n}\n\n.doc h6 {\n font-size: 1.3em;\n}\n\n.doc h1,\n.doc h2,\n.doc h3,\n.doc h4,\n.doc h5,\n.doc h6 {\n color: var(--asciidoctor-heading-font-color);\n font-weight: var(--asciidoctor-heading-font-weight);\n hyphens: none;\n line-height: 1.3;\n margin: 1.3rem 0 0;\n padding-top: 1.8rem;\n}\n\n.doc h1.sect0 {\n background: var(--asciidoctor-abstract-background);\n font-size: 1.8em;\n margin: 1.5rem -1rem 0;\n padding: 0.5rem 1rem;\n}\n\n.doc h1:first-child {\n margin: 1.3rem 0;\n}\n\n.doc h2:not(.discrete) {\n margin-left: -1rem;\n margin-right: -1rem;\n padding: 1.8rem 1rem 0.1rem;\n}\n\n.doc h3:not(.discrete) {\n font-weight: var(--asciidoctor-alt-heading-font-weight);\n}\n\n/* Header hover anchors */\n\n.doc h1 .anchor,\n.doc h2 .anchor,\n.doc h3 .anchor,\n.doc h4 .anchor,\n.doc h5 .anchor,\n.doc h6 .anchor {\n position: absolute;\n text-decoration: none;\n width: 2.25ex;\n margin-left: -2ex;\n padding-left: 0.5ex;\n visibility: hidden;\n font-weight: normal;\n}\n\n.doc h1 .anchor::before,\n.doc h2 .anchor::before,\n.doc h3 .anchor::before,\n.doc h4 .anchor::before,\n.doc h5 .anchor::before,\n.doc h6 .anchor::before {\n content: \"\\0023\";\n}\n\n.doc h1:hover .anchor,\n.doc h2:hover .anchor,\n.doc h3:hover .anchor,\n.doc h4:hover .anchor,\n.doc h5:hover .anchor,\n.doc h6:hover .anchor {\n visibility: visible;\n}\n\n.doc p,\n.doc dl {\n margin: 0;\n}\n\n/* General anchors */\n\n.doc a.bare {\n hyphens: none;\n}\n\n.doc a {\n color: var(--asciidoctor-link-font-color);\n}\n\n.doc a:hover {\n color: var(--asciidoctor-hover-link-font-color);\n}\n\n.doc a.unresolved {\n color: var(--asciidoctor-unresolved-link-font-color);\n}\n\n/* Code and Pre */\n\n.doc p code,\n.doc thead code,\n.doc .admonitionblock code {\n color: var(--asciidoctor-code-font-color);\n background: var(--asciidoctor-code-background);\n border-radius: 0.25em;\n font-size: 0.95em;\n padding: 0.125em 0.25em;\n}\n\n.doc p a code,\n.doc thead a code,\n.doc .admonitionblock a code {\n color: var(--asciidoctor-code-link-font-color);\n}\n\n.doc code,\n.doc pre {\n hyphens: none;\n}\n\n.doc pre {\n font-size: calc(14 / var(--pixel-to-rem));\n line-height: 1.3;\n margin: 0;\n}\n\n.doc pre.highlight code,\n.doc .listingblock pre:not(.highlight),\n.doc .literalblock pre {\n background: var(--asciidoctor-pre-background);\n box-shadow: inset 0 0 1.75px var(--asciidoctor-pre-border-color);\n display: block;\n overflow-x: auto;\n padding: 0.95rem;\n border-radius: 4px;\n}\n\n.doc pre.highlight code[data-lang]:before {\n content: attr(data-lang);\n text-transform: uppercase;\n display: block;\n position: absolute;\n top: 0.3rem;\n right: 0.3rem;\n line-height: 1;\n font-size: 0.65em;\n color: var(--asciidoctor-code-data-lang-color);\n}\n\n.doc pre.highlight {\n position: relative;\n}\n\n.doc table pre.highlight code[data-lang]:before {\n display: none;\n}\n\n/* General margin and fonts sizing */\n\n.doc blockquote {\n margin: 0;\n}\n\n.doc .paragraph.lead > p {\n font-size: calc(18 / var(--pixel-to-rem));\n}\n\n.doc .paragraph,\n.doc .dlist,\n.doc .hdlist,\n.doc .olist,\n.doc .ulist,\n.doc .exampleblock,\n.doc .imageblock,\n.doc .listingblock,\n.doc .literalblock,\n.doc .sidebarblock,\n.doc .verseblock,\n.doc .quoteblock,\n.doc .partintro,\n.doc details,\n.doc hr {\n margin: 1rem 0 0;\n}\n\n/* Tables */\n\n.doc table.tableblock {\n display: block;\n width: 100%;\n overflow-x: auto;\n}\n\n.doc table.tableblock td {\n min-width: 6rem;\n}\n\n.doc table.tableblock {\n font-size: calc(15 / var(--pixel-to-rem));\n margin: 1.5rem 0 0;\n}\n\n.doc table.tableblock + * {\n margin-top: 2rem;\n}\n\n.doc td.tableblock > .content > :first-child {\n margin-top: 0;\n}\n\n.doc table.tableblock th,\n.doc table.tableblock td {\n padding: 0.5rem;\n}\n\n.doc table.tableblock thead th {\n border-bottom: 2.5px solid var(--asciidoctor-table-border-color);\n}\n\n.doc table.tableblock td,\n.doc table.tableblock > :not(thead) th {\n border-top: 1px solid var(--asciidoctor-table-border-color);\n border-bottom: 1px solid var(--asciidoctor-table-border-color);\n}\n\n.doc table.stripes-all > tbody > tr,\n.doc table.stripes-odd > tbody > tr:nth-of-type(odd),\n.doc table.stripes-even > tbody > tr:nth-of-type(even),\n.doc table.stripes-hover > tbody > tr:hover {\n background: var(--asciidoctor-table-stripe-background);\n}\n\n.doc table.tableblock > tfoot {\n background: var(--asciidoctor-table-footer-background);\n}\n\n.doc .tableblock pre,\n.doc .tableblock code,\n.doc .listingblock.wrap pre {\n white-space: pre-wrap;\n}\n\n.doc td:nth-child(1) .tableblock pre,\n.doc td:nth-child(1) .tableblock code,\n.doc td:nth-child(1) .listingblock.wrap pre {\n white-space: nowrap;\n}\n\n/* Admonition blocks */\n\n.doc .admonitionblock {\n margin: 2.5rem 0;\n}\n\n.doc .admonitionblock p,\n.doc .admonitionblock td.content {\n font-size: calc(16 / var(--pixel-to-rem));\n}\n\n.doc .admonitionblock td.content > :not(.title):first-child,\n.doc .admonitionblock td.content > .title + * {\n margin-top: 0;\n}\n\n.doc .admonitionblock pre {\n font-size: calc(14 / var(--pixel-to-rem));\n border: none;\n}\n\n.doc .admonitionblock > table {\n table-layout: fixed;\n position: relative;\n width: 100%;\n}\n\n.doc .admonitionblock td.content {\n padding: 1rem 1rem 0.75rem;\n background: var(--asciidoctor-admonition-background);\n width: 100%;\n word-wrap: anywhere;\n}\n\n.doc .admonitionblock td.icon {\n position: absolute;\n top: 0;\n left: 0;\n font-size: calc(16 / var(--pixel-to-rem));\n line-height: 1;\n transform: translate(-0.5rem, -50%);\n border-radius: 0.45rem;\n padding: 0.25em 0.075em;\n}\n\n.doc .admonitionblock .icon i {\n display: inline-flex;\n align-items: center;\n width: auto;\n height: 16px;\n background-repeat: no-repeat;\n background-position: 0.5em 0;\n filter: invert(100%);\n padding-left: 2em;\n vertical-align: initial;\n}\n\n.doc .admonitionblock .icon i::after {\n border-left: 1px solid rgba(255, 255, 255, 0.3);\n content: attr(title);\n text-transform: capitalize;\n filter: invert(100%);\n font-weight: var(--asciidoctor-admonition-label-font-weight);\n color: var(--asciidoctor-admonition-font-color);\n font-style: normal;\n hyphens: none;\n padding: 0 0.5em;\n margin: -0.05em;\n}\n\ni.fa {\n background-size: 16px 16px;\n}\n\ni.fa.icon-caution {\n background-image: url(\"../img/octicons-16.svg#view-flame\");\n}\n\ni.fa.icon-important {\n background-image: url(\"../img/octicons-16.svg#view-stop\");\n}\n\ni.fa.icon-note {\n background-image: url(\"../img/octicons-16.svg#view-info\");\n}\n\ni.fa.icon-tip {\n background-image: url(\"../img/octicons-16.svg#view-light-bulb\");\n}\n\ni.fa.icon-warning {\n background-image: url(\"../img/octicons-16.svg#view-alert\");\n}\n\n.doc .admonitionblock.caution td.icon {\n background: var(--asciidoctor-admonition-caution-background);\n}\n\n.doc .admonitionblock.important td.icon {\n background: var(--asciidoctor-admonition-important-background);\n}\n\n.doc .admonitionblock.note .icon {\n background: var(--asciidoctor-admonition-note-background);\n}\n\n.doc .admonitionblock.tip .icon {\n background: var(--asciidoctor-admonition-tip-background);\n}\n\n.doc .admonitionblock.warning .icon {\n background-color: var(--asciidoctor-admonition-warning-background);\n}\n\n/* Images and image blocks */\n\n.doc .imageblock {\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n.doc .imageblock img,\n.doc .image > img {\n display: inline-block;\n height: auto;\n max-width: 100%;\n vertical-align: middle;\n}\n\n.doc .image:not(.left):not(.right) > img {\n margin-top: -0.2em;\n}\n\n/* Quote blocks */\n\n.doc #preamble .abstract blockquote {\n background: var(--asciidoctor-abstract-background);\n border-left: 5px solid var(--asciidoctor-abstract-border-color);\n font-size: calc(16 / var(--pixel-to-rem));\n padding: 0.75em 1em;\n}\n\n.doc .quoteblock,\n.doc .verseblock {\n background: var(--asciidoctor-quote-background);\n border-left: 5px solid var(--asciidoctor-quote-border-color);\n}\n\n.doc .quoteblock {\n padding: 0.25rem 2rem 1.25rem;\n}\n\n.doc .quoteblock .attribution {\n color: var(--asciidoctor-quote-attribution-font-color);\n font-size: calc(15 / var(--pixel-to-rem));\n margin-top: 0.75rem;\n}\n\n.doc .quoteblock blockquote {\n margin-top: 1rem;\n}\n\n.doc .quoteblock .paragraph {\n font-style: italic;\n}\n\n.doc .quoteblock cite {\n padding-left: 1em;\n}\n\n/* Verse blocks */\n\n.doc .verseblock {\n font-size: 1.15em;\n padding: 1rem 2rem;\n}\n\n.doc .verseblock pre {\n font-family: inherit;\n font-size: inherit;\n}\n\n/* Lists */\n\n.doc ol,\n.doc ul {\n margin: 0;\n padding: 0 0 0 2rem;\n}\n\n.doc ul.checklist,\n.doc ul.none,\n.doc ol.none,\n.doc ul.no-bullet,\n.doc ol.unnumbered,\n.doc ul.unstyled,\n.doc ol.unstyled {\n list-style-type: none;\n}\n\n.doc ul.no-bullet,\n.doc ol.unnumbered {\n padding-left: 1.25rem;\n}\n\n.doc ul.unstyled,\n.doc ol.unstyled {\n padding-left: 0;\n}\n\n.doc ul.circle {\n list-style-type: square;\n}\n\n.doc ul.disc {\n list-style-type: square;\n}\n\n.doc ul.square {\n list-style-type: square;\n}\n\n.doc ol.arabic {\n list-style-type: decimal;\n}\n\n.doc ol.decimal {\n list-style-type: decimal-leading-zero;\n}\n\n.doc ol.loweralpha {\n list-style-type: lower-alpha;\n}\n\n.doc ol.upperalpha {\n list-style-type: upper-alpha;\n}\n\n.doc ol.lowerroman {\n list-style-type: lower-roman;\n}\n\n.doc ol.upperroman {\n list-style-type: upper-roman;\n}\n\n.doc ol.lowergreek {\n list-style-type: lower-greek;\n}\n\n.doc ul.checklist {\n padding-left: 0.5rem;\n}\n\n.doc ul.checklist p > i.fa-check-square-o:first-child,\n.doc ul.checklist p > i.fa-square-o:first-child {\n display: inline-flex;\n justify-content: center;\n width: 1.25rem;\n}\n\n.doc ul.checklist i.fa-check-square-o::before {\n content: \"\\2713\";\n}\n\n.doc ul.checklist i.fa-square-o::before {\n content: \"\\274f\";\n}\n\n.doc .dlist .dlist,\n.doc .dlist .olist,\n.doc .dlist .ulist,\n.doc .olist .dlist,\n.doc .olist .olist,\n.doc .olist .ulist,\n.doc .ulist .dlist,\n.doc .ulist .olist,\n.doc .ulist .ulist {\n margin-top: 0.5rem;\n}\n\n.doc .olist li,\n.doc .ulist li {\n margin-bottom: 0.3rem;\n}\n\n.doc .ulist .listingblock,\n.doc .olist .listingblock,\n.doc .admonitionblock .listingblock {\n padding: 0;\n}\n\n/* Block Titles */\n\n.doc .admonitionblock .title,\n.doc .exampleblock .title,\n.doc .imageblock .title,\n.doc .literalblock .title,\n.doc .listingblock .title,\n.doc .openblock .title,\n.doc .tableblock caption {\n color: var(--asciidoctor-caption-font-color);\n font-size: calc(14 / var(--pixel-to-rem));\n font-weight: var(--asciidoctor-caption-font-weight);\n font-style: italic;\n hyphens: none;\n letter-spacing: 0.01em;\n padding-bottom: 0.075rem;\n text-align: left;\n}\n\n.doc .imageblock .title {\n margin-top: 0.5rem;\n padding-bottom: 0;\n}\n\n/* Block content */\n\n.doc .exampleblock > .content {\n background: var(--asciidoctor-example-background);\n border: 1px solid var(--asciidoctor-example-border-color);\n border-radius: 4px;\n padding: 0.75rem;\n}\n\n.doc .exampleblock > .content > :first-child {\n margin-top: 0;\n}\n\n/* Sidebars */\n\n.doc .sidebarblock {\n background: var(--asciidoctor-sidebar-background);\n padding: 2.2rem 2.2rem;\n}\n\n.doc .sidebarblock > .content > .title {\n font-size: calc(23 / var(--pixel-to-rem));\n font-weight: var(--asciidoctor-alt-heading-font-weight);\n line-height: 1.3;\n margin-bottom: 1.2rem;\n}\n\n.doc .sidebarblock > .content > :not(.title):first-child {\n margin-top: 0;\n}\n\n/* Buttons (https://docs.asciidoctor.org/asciidoc/latest/macros/ui-macros/#button-macro-syntax) */\n\n.doc b.button {\n white-space: nowrap;\n}\n\n.doc b.button::before {\n content: \"[\";\n padding-right: 0.25em;\n}\n\n.doc b.button::after {\n content: \"]\";\n padding-left: 0.25em;\n}\n\n/* Menu (https://docs.asciidoctor.org/asciidoc/latest/macros/ui-macros/#menu-macro-syntax) */\n\n.doc .menuseq,\n.doc .path {\n hyphens: none;\n}\n\n.doc .menuseq i.caret::before {\n content: \"\\203a\";\n font-size: 1.1em;\n font-weight: var(--asciidoctor-body-font-weight-bold);\n line-height: calc(1 / 1.1);\n}\n\n/* Keyboard (https://docs.asciidoctor.org/asciidoc/latest/macros/keyboard-macro/) */\n\n.doc kbd {\n display: inline-block;\n font-size: calc(12 / var(--pixel-to-rem));\n background: var(--asciidoctor-kbd-background);\n border: 1px solid var(--asciidoctor-kbd-border-color);\n border-radius: 0.25em;\n box-shadow: 0 1px 0 var(--asciidoctor-kbd-border-color),\n 0 0 0 0.1em var(--body-background) inset;\n padding: 0.25em 0.5em;\n vertical-align: text-bottom;\n white-space: nowrap;\n}\n\n.doc kbd,\n.doc .keyseq {\n line-height: 1;\n}\n\n.doc .keyseq {\n font-size: calc(16 / var(--pixel-to-rem));\n}\n\n.doc .keyseq kbd {\n margin: 0 0.125em;\n}\n\n.doc .keyseq kbd:first-child {\n margin-left: 0;\n}\n\n.doc .keyseq kbd:last-child {\n margin-right: 0;\n}\n\n/* Misc */\n\n.doc i.fa {\n hyphens: none;\n font-style: normal;\n}\n\n.doc .language-console .hljs-meta {\n user-select: none;\n}\n\n.doc .dlist dt {\n font-style: italic;\n}\n\n.doc .dlist dd {\n margin: 0 0 0.25rem 1.5rem;\n}\n\n.doc .dlist dd:last-of-type {\n margin-bottom: 0;\n}\n\n.doc td.hdlist1,\n.doc td.hdlist2 {\n padding: 0.5rem 0 0;\n vertical-align: top;\n}\n\n.doc tr:first-child > .hdlist1,\n.doc tr:first-child > .hdlist2 {\n padding-top: 0;\n}\n\n.doc td.hdlist1 {\n font-weight: var(--body-font-weight-bold);\n padding-right: 0.25rem;\n}\n\n.doc td.hdlist2 {\n padding-left: 0.25rem;\n}\n\n.doc .colist {\n font-size: calc(16 / var(--pixel-to-rem));\n margin: 0.25rem 0 -0.25rem;\n}\n\n.doc .colist > table > tr > :first-child,\n.doc .colist > table > tbody > tr > :first-child {\n padding: 0.25em 0.5rem 0;\n vertical-align: top;\n}\n\n.doc .colist > table > tr > :last-child,\n.doc .colist > table > tbody > tr > :last-child {\n padding: 0.25rem 0;\n}\n\n.doc .conum[data-value] {\n /* border: 1px solid currentColor; */\n font-family: var(--monospace-font-family);\n border-radius: 100%;\n display: inline-block;\n font-size: calc(12.5 / var(--pixel-to-rem));\n font-style: normal;\n line-height: 1.2;\n text-align: center;\n width: 1.25em;\n height: 1.25em;\n letter-spacing: -0.25ex;\n text-indent: -0.25ex;\n background: var(--asciidoctor-callout-background);\n color: var(--asciidoctor-callout-font-color);\n}\n\n.doc .conum[data-value]::after {\n content: attr(data-value);\n}\n\n.doc .conum[data-value] + b {\n display: none;\n}\n\n.doc hr {\n border: solid var(--asciidoctor-section-divider-color);\n border-width: 2px 0 0;\n height: 0;\n}\n\n/* Pass-though Classes */\n\n.doc :not(pre).nowrap {\n white-space: nowrap;\n}\n\n.doc .nobreak {\n hyphens: none;\n word-wrap: normal;\n}\n\n.doc .right {\n float: right;\n}\n\n.doc .left {\n float: left;\n}\n\n.doc .stretch {\n width: 100%;\n}\n\n.doc .underline {\n text-decoration: underline;\n}\n\n.doc .line-through {\n text-decoration: line-through;\n}\n\n.doc .halign-left {\n text-align: left;\n}\n\n.doc .halign-right {\n text-align: right;\n}\n\n.doc .halign-center {\n text-align: center;\n}\n\n.doc .valign-top {\n vertical-align: top;\n}\n\n.doc .valign-bottom {\n vertical-align: bottom;\n}\n\n.doc .valign-middle {\n vertical-align: middle;\n}\n\n/* Footer */\n\n#footer #footer-text {\n font-size: calc(14 / var(--pixel-to-rem));\n color: var(--asciidoctor-footer-font-color);\n padding: 2rem 0;\n border-top: 1px solid var(--asciidoctor-section-divider-color);\n}\n\n/* Responsive and Dark Theme Overrides */\n\nhtml.dark-theme #doc {\n background: no-repeat top right / 305px 147px;\n background-image: url(\"../img/doc-background-dark.svg\");\n}\n\n@media screen and (max-width: 1024px) {\n #doc {\n background: no-repeat top right / 203px 95px;\n background-image: url(\"../img/doc-background.svg\");\n }\n html.dark-theme #doc {\n background: no-repeat top right / 203px 95px;\n background-image: url(\"../img/doc-background-dark.svg\");\n }\n}\n\n@media screen and (max-width: 800px) {\n html.dark-theme #doc,\n #doc {\n background: none;\n }\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n.hljs {\n display: block;\n overflow-x: auto;\n padding: 0.5em;\n background: var(--highlight-background-color);\n color: var(--highlight-font-color);\n}\n\n.hljs-keyword,\n.hljs-selector-tag,\n.hljs-subst {\n color: var(--highlight-keyword-font-color);\n}\n\n.hljs-comment,\n.hljs-quote {\n color: var(--highlight-comment-font-color);\n}\n\n.hljs-string,\n.hljs-doctag {\n color: var(--highlight-string-font-color);\n}\n\n.hljs-meta {\n color: var(--highlight-meta-font-color);\n}\n\n.hljs-built_in,\n.hljs-builtin-name,\n.hljs-number,\n.hljs-symbol,\n.hljs-literal {\n color: var(--highlight-constant-font-color);\n}\n\n.hljs-variable,\n.hljs-template-variable {\n color: var(--highlight-variable-font-color);\n}\n\n.hljs-tag,\n.hljs-name,\n.hljs-attribute {\n color: var(--highlight-tag-font-color);\n}\n\n.hljs-tag .hljs-attr {\n color: var(--highlight-tag-attribute-font-color);\n}\n\n.hljs-type,\n.hljs-class .hljs-title {\n color: var(--highlight-type-font-color);\n}\n\n.hljs-regexp {\n color: var(--highlight-regex-font-color);\n}\n\n.hljs-link {\n text-decoration: underline;\n color: var(--highlight-link-font-color);\n}\n\n.hljs-addition {\n color: var(--highlight-addition-font-color);\n}\n\n.hljs-deletion {\n color: var(--highlight-deletion-font-color);\n}\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n\n.language-json .hljs-number,\n.language-json .hljs-literal {\n color: var(--highlight-variable-font-color);\n}\n\n.language-json .hljs-attr {\n color: var(--highlight-string-font-color);\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* Block Switching */\n\n.hidden {\n display: none;\n}\n\n.doc .tabs {\n font-weight: bold;\n font-size: calc(12 / var(--pixel-to-rem));\n border-style: none;\n display: inline-block;\n position: relative;\n bottom: 0;\n margin-top: 0.5rem;\n margin-bottom: calc(2 / var(--pixel-to-rem));\n}\n\n.doc .tab:not(:first-child) {\n border: 1px solid var(--tabs-border-color);\n}\n\n.doc .tab {\n padding: 0.3rem 0.6rem;\n background-color: var(--tabs-background-color);\n color: var(--tabs-font-color);\n display: inline-block;\n cursor: pointer;\n border: 1px solid var(--tabs-border-color);\n margin-bottom: calc(2 / var(--pixel-to-rem));\n border-radius: 0;\n transition: background-color 200ms;\n}\n\n.doc .tab:hover {\n color: var(--tabs-hover-font-color);\n background-color: var(--tabs-hover-background);\n text-decoration: underline;\n}\n\n.doc .tab.selected {\n background-color: var(--tabs-selected-background-color);\n border-color: var(--tabs-selected-background-color);\n color: var(--tabs-selected-font-color);\n}\n\n.doc .tab.selected:hover {\n color: var(--tabs-selected-font-color);\n text-decoration: none;\n}\n\n.doc div.openblock.tabs-content > .content {\n padding: 1rem;\n background-color: var(--tabs-group-background-color);\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nbody.toc-left #doc {\n border-left: 1px solid var(--layout-border-color);\n overflow: auto;\n margin-left: var(--toc-width);\n}\n\n#toc {\n display: var(--toc-display);\n position: absolute;\n top: var(--layout-banner-height);\n width: var(--toc-width);\n margin-left: calc(var(--toc-width) * -1);\n border-right: 1px solid var(--layout-border-color);\n padding: 1.7rem 1rem 0 1rem;\n font-size: 0.95rem;\n line-height: 1.1;\n}\n\n#toctitle {\n display: none;\n}\n\n#toc ul,\n#toc ol {\n padding: 0;\n}\n\n#toc ul ul,\n#toc ul ol {\n padding-left: 0.8rem;\n}\n\n#toc li {\n display: block;\n list-style: none;\n}\n\n#toc a {\n display: block;\n text-decoration: none;\n color: var(--toc-font-color);\n padding: 0.4rem 0.6rem;\n border-radius: 4px;\n}\n\n#toc a:hover {\n background-color: var(--toc-hover-background-color);\n}\n\nbody.fixed-toc #toc {\n position: fixed;\n top: 0;\n overflow-x: hidden;\n height: 100%;\n}\n\n#toc li.active > a {\n background-color: var(--toc-active-background-color);\n color: var(--toc-active-font-color);\n}\n\n#toc > ul ul,\n#toc > ol ol {\n display: none;\n}\n\n#toc li.active > ul,\n#toc li.active > ol,\n#toc ul.expanded,\n#toc ol.expanded {\n display: block;\n}\n\n#back-to-index {\n display: block;\n margin-bottom: 0.6rem;\n}\n\n#back-to-index a {\n padding-left: 1.6rem;\n margin-bottom: 0.6rem;\n margin-top: -0.9rem;\n}\n\n#back-to-index a::before {\n content: \"\";\n filter: var(--toc-back-to-index-filter);\n background: no-repeat center / 16px 16px;\n background-image: url(\"../img/octicons-16.svg#view-chevron-left\");\n display: block;\n position: absolute;\n min-width: 16px;\n min-height: 16px;\n left: 1.4rem;\n}\n\n#tocbar-container {\n display: var(--toc-bar-display);\n width: 100%;\n}\n\n#tocbar-container {\n height: var(--tocbar-height);\n background-color: var(--body-background-color);\n border-bottom: 1px solid var(--panel-border-color);\n z-index: 10000;\n}\n\n#tocbar {\n width: 100%;\n height: 100%;\n padding-left: 6px;\n}\n\nbody.fixed-toc #tocbar-container {\n position: fixed;\n top: 0;\n}\n\nbutton#toggle-toc {\n width: var(--toc-bar-height);\n height: var(--toc-bar-height);\n filter: var(--toc-bar-button-filter);\n background: no-repeat center / 16px 16px;\n background-image: url(\"../img/octicons-16.svg#view-three-bars\");\n border: none;\n outline: none;\n padding: 0;\n display: block;\n}\n\nbody.show-toc button#toggle-toc {\n background-image: url(\"../img/octicons-16.svg#view-x\");\n}\n\n@media screen and (max-width: 800px) {\n body.fixed-toc #toc {\n top: var(--toc-bar-height);\n }\n\n #toc {\n top: calc(var(--layout-banner-height) + var(--toc-bar-height));\n width: 100%;\n height: 100%;\n left: 0;\n background-color: var(--body-background-color);\n z-index: 10000;\n }\n\n body.show-toc #toc {\n display: block;\n }\n}\n", + "/*\n * Copyright 2021 the original author or authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ndiv.codetools {\n --button-width: 28px;\n --button-height: 24px;\n --arrow-size: 5px;\n display: flex;\n position: absolute;\n bottom: 9px;\n right: 8px;\n background: var(--codetools-background-color);\n padding: 0;\n border-radius: 2px;\n border: 1px solid var(--codetools-border-color);\n opacity: 0;\n transition: opacity 150ms ease-in-out;\n}\n\n.doc pre.highlight:hover div.codetools {\n opacity: 1;\n}\n\ndiv.codetools button {\n width: var(--button-width);\n height: var(--button-height);\n filter: var(--codetools-button-filter);\n background: no-repeat center / 16px 16px;\n border: none;\n padding: 0;\n outline: none;\n}\n\ndiv.codetools button:not(:last-child) {\n border-right: 1px solid var(--codetools-divider-color);\n}\n\ndiv.codetools button:hover {\n background-color: var(--codetools-hover-background-color);\n transition: filter 300ms;\n}\n\ndiv.codetools button:active {\n filter: var(--codetools-button-active-filter);\n transition: filter none;\n}\n\ndiv.codetools button span.label {\n display: none;\n}\n\ndiv.codetools button.copy-button {\n background-image: url(\"../img/octicons-16.svg#view-clippy\");\n}\n\ndiv.codetools button.unfold-button {\n background-image: url(\"../img/octicons-16.svg#view-unfold\");\n}\n\ndiv.codetools button.fold-button {\n background-image: url(\"../img/octicons-16.svg#view-fold\");\n}\n\ndiv.codetools span.copied {\n opacity: 0;\n display: block;\n content: \"\";\n position: relative;\n width: var(--button-width);\n height: var(--button-height);\n z-index: 1000000;\n transition: opacity 500ms;\n}\n\ndiv.codetools button:active span.copied {\n filter: invert();\n transition: filter none;\n}\n\ndiv.codetools span.copied:before {\n position: absolute;\n bottom: calc(var(--arrow-size) * -1);\n left: 50%;\n margin-left: calc(var(--arrow-size) / -2);\n content: \"\";\n border: var(--arrow-size) solid var(--codetools-popup-background-color);\n border-color: transparent transparent var(--codetools-popup-background-color)\n transparent;\n}\n\ndiv.codetools span.copied:after {\n content: \"Copied to clipboard!\";\n position: absolute;\n top: calc(var(--button-height) + var(--arrow-size));\n right: 100%;\n margin-right: calc(var(--button-width) * -1);\n background-color: var(--codetools-popup-background-color);\n color: var(--codetools-popup-font-color);\n padding: 5px 8px;\n border-radius: 3px;\n font-weight: bold;\n}\n\ndiv.codetools button.clicked span.copied {\n opacity: 1;\n}\n\nspan.fold-block {\n position: relative;\n float: left;\n clear: left;\n padding-right: 0.75rem;\n overflow: hidden;\n}\n\ncode.unfolded span.fold-block.hide-when-folded,\ncode:not(.unfolded) span.fold-block.hide-when-unfolded {\n max-height: 99999px;\n opacity: 1;\n}\n\ncode.unfolded span.fold-block.hide-when-unfolded,\ncode:not(.unfolded) span.fold-block.hide-when-folded {\n max-height: 0px;\n opacity: 0;\n}\n\ncode.unfolding span.fold-block.hide-when-folded {\n max-height: 600px;\n opacity: 1;\n}\n\ncode.folding span.fold-block.hide-when-unfolded {\n max-height: 400px;\n opacity: 1;\n}\n\ncode.unfolding span.fold-block.hide-when-unfolded,\ncode.folding span.fold-block.hide-when-folded {\n max-height: 0;\n opacity: 0;\n}\n\ncode.unfolding span.fold-block.hide-when-unfolded {\n transition: max-height 200ms cubic-bezier(0, 1, 0, 1), opacity 200ms linear;\n}\n\ncode.folding span.fold-block.hide-when-unfolded {\n transition: max-height 200ms cubic-bezier(1, 0, 1, 0), opacity 200ms linear;\n}\n\ncode.unfolding span.fold-block.hide-when-folded {\n transition: max-height 200ms cubic-bezier(1, 0, 1, 0), opacity 200ms linear;\n}\n\ncode.folding span.fold-block.hide-when-folded {\n transition: max-height 200ms cubic-bezier(0, 1, 0, 1), opacity 200ms linear;\n}\n" + ] +} \ No newline at end of file diff --git a/applications/rest-service/src/main/resources/static/img/banner-logo.svg b/applications/spring-boot-upgrade/src/main/resources/static/img/banner-logo.svg similarity index 100% rename from applications/rest-service/src/main/resources/static/img/banner-logo.svg rename to applications/spring-boot-upgrade/src/main/resources/static/img/banner-logo.svg diff --git a/applications/rest-service/src/main/resources/static/img/doc-background-dark.svg b/applications/spring-boot-upgrade/src/main/resources/static/img/doc-background-dark.svg similarity index 100% rename from applications/rest-service/src/main/resources/static/img/doc-background-dark.svg rename to applications/spring-boot-upgrade/src/main/resources/static/img/doc-background-dark.svg diff --git a/applications/rest-service/src/main/resources/static/img/doc-background.svg b/applications/spring-boot-upgrade/src/main/resources/static/img/doc-background.svg similarity index 100% rename from applications/rest-service/src/main/resources/static/img/doc-background.svg rename to applications/spring-boot-upgrade/src/main/resources/static/img/doc-background.svg diff --git a/applications/rest-service/src/main/resources/static/img/octicons-16.svg b/applications/spring-boot-upgrade/src/main/resources/static/img/octicons-16.svg similarity index 100% rename from applications/rest-service/src/main/resources/static/img/octicons-16.svg rename to applications/spring-boot-upgrade/src/main/resources/static/img/octicons-16.svg diff --git a/applications/spring-boot-upgrade/src/main/resources/static/js/java.min.js b/applications/spring-boot-upgrade/src/main/resources/static/js/java.min.js new file mode 100644 index 000000000..c83bc753c --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/static/js/java.min.js @@ -0,0 +1 @@ +hljs.registerLanguage("java",function(e){var a="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",t={cN:"number",b:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0};return{aliases:["jsp"],k:a,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{relevance:0,c:[{b:/\w+@/,relevance:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",relevance:0},{cN:"function",b:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:a,c:[{b:e.UIR+"\\s*\\(",rB:!0,relevance:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:a,relevance:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},t,{cN:"meta",b:"@[A-Za-z]+"}]}}); \ No newline at end of file diff --git a/applications/spring-boot-upgrade/src/main/resources/static/js/recipe.js b/applications/spring-boot-upgrade/src/main/resources/static/js/recipe.js new file mode 100644 index 000000000..97a3923a4 --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/static/js/recipe.js @@ -0,0 +1,182 @@ +class State { + + constructor() { + this.runningARecipe = false; + this.listeners = []; + } + + isRunningARecipe() { + return this.runningARecipe; + } + + startedRunningRecipe() { + this.runningARecipe = true; + // disable all other buttons + console.log($("button")) + this.notifyListeners(); + } + + completedRunningRecipe() { + this.runningARecipe = false; + this.notifyListeners(); + } + + notifyListeners() { + + this.listeners.forEach((func) => { + func(); + }); + } + + registerListeners(func) { + this.listeners.push(func) + } +} + +const state = new State(); +/* +function runRecipe(element) { + if (state.isRunningARecipe()) { + return; + } + state.startedRunningRecipe(); + + $.ajax({ + type: "POST", + url: "http://localhost:8080/spring-boot-upgrade", + data: JSON.stringify({ + recipe: $(element).attr('recipe') + }), + dataType: "json", + contentType: 'application/json', + processData: false + }) + .always(function () { + state.completedRunningRecipe(); + }); +} +*/ +/** + * + */ +function applyRecipes(btn) { + + const recipeName = $(btn).attr('recipe'); + + if (state.isRunningARecipe()) { + return; + } + + $.ajax({ + type: "POST", + url: "http://localhost:8080/spring-boot-upgrade", + contentType: 'application/json', + data: JSON.stringify({ + recipes: [$(btn).attr('recipe')] + }), + beforeSend: function() { + state.startedRunningRecipe(); + }, + error: function(e) { + // mark red flashlights / play alarm sound + console.log("Error while applying recipe: " + e) + } + }).done(function () { + // After applying recipe + var section = $(`.run-a-recipe[recipe='${recipeName}']`).closest(".sect2"); + + let sectionH3 = section.find("h3"); + // find next h3 + let nextH3 = section.parent().find("h3").has("a.anchor").slice(1); + let title = sectionH3.text(); + // fade out section + section.fadeOut( 1000, "linear", function() { + // and remove section + section.remove(); + }); + // fade out sidebar section + let sidebar = $("a:contains('" + title + "')").parent().remove() + sidebar.fadeOut( 1000, "linear", function() { + // and remove section + sidebar.remove(); + }); + scrollToAnchor(nextH3); + }) + .always(function () { + state.completedRunningRecipe(); + }); +} + + +function scrollToAnchor(aid){ + $('html,body').animate({scrollTop: aid.offset().top},'fast'); +} + + +$( document ).ajaxStart(function() { + $( ".log" ).text( "Triggered ajaxStart handler." ); +}); + + +state.registerListeners(function () { + + // changeAllRecipesButtonState(); + changeRecipeButtonState(); +}) + +function changeRecipeButtonState() { + + state.isRunningARecipe() ? runRecipeDisabledState() : runRecipeNormalState(); +} +/* +function changeAllRecipesButtonState() { + + $(".run-all-recipe").html( + state.isRunningARecipe() ? runAllRecipeInLoadingState : + runAllRecipeInNormalState + ); +} + +const runAllRecipeInLoadingState = ''; + +const runAllRecipeInNormalState = ''; +*/ +$(document).ready(function () { + // $(".run-all-recipe").html(runAllRecipeInNormalState); + + runRecipeNormalState(); +}); + +const runRecipeNormalState = function () { + $(".run-a-recipe").each(function () { + const div = $(this); + div.html('
'); + }); +} + +const runRecipeDisabledState = function () { + $(".run-a-recipe").each(function () { + const div = $(this); + div.html('
'); + }); +} diff --git a/applications/rest-service/src/main/resources/static/js/setup.js b/applications/spring-boot-upgrade/src/main/resources/static/js/setup.js similarity index 100% rename from applications/rest-service/src/main/resources/static/js/setup.js rename to applications/spring-boot-upgrade/src/main/resources/static/js/setup.js diff --git a/applications/rest-service/src/main/resources/static/js/setup.js.map b/applications/spring-boot-upgrade/src/main/resources/static/js/setup.js.map similarity index 100% rename from applications/rest-service/src/main/resources/static/js/setup.js.map rename to applications/spring-boot-upgrade/src/main/resources/static/js/setup.js.map diff --git a/applications/spring-boot-upgrade/src/main/resources/static/js/setup2.js b/applications/spring-boot-upgrade/src/main/resources/static/js/setup2.js new file mode 100644 index 000000000..ae5b1b7bd --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/static/js/setup2.js @@ -0,0 +1,3 @@ +!function(){"use strict";document.getElementsByTagName("html")[0].classList.add("js")}(); +!function(){var t=function(t,n,e){if("function"!=typeof t)throw new TypeError("Expected a function");return setTimeout((function(){t.apply(void 0,e)}),n)};var n=function(t){return t};var e=function(t,n,e){switch(e.length){case 0:return t.call(n);case 1:return t.call(n,e[0]);case 2:return t.call(n,e[0],e[1]);case 3:return t.call(n,e[0],e[1],e[2])}return t.apply(n,e)},r=Math.max;var o=function(t,n,o){return n=r(void 0===n?t.length-1:n,0),function(){for(var c=arguments,u=-1,i=r(c.length-n,0),a=Array(i);++u0){if(++n>=800)return arguments[0]}else n=0;return t.apply(void 0,arguments)}},D=C(R);var G=/\s/;var U=function(t){for(var n=t.length;n--&&G.test(t.charAt(n)););return n},z=/^\s+/;var B=function(t){return t?t.slice(0,U(t)+1).replace(z,""):t};var H=function(t){return null!=t&&"object"==typeof t};var J=function(t){return"symbol"==typeof t||H(t)&&"[object Symbol]"==g(t)},K=/^[-+]0x[0-9a-f]+$/i,Q=/^0b[01]+$/i,V=/^0o[0-7]+$/i,W=parseInt;var X=function(t){if("number"==typeof t)return t;if(J(t))return NaN;if(m(t)){var n="function"==typeof t.valueOf?t.valueOf():t;t=m(n)?n+"":n}if("string"!=typeof t)return 0===t?t:+t;t=B(t);var e=Q.test(t);return e||V.test(t)?W(t.slice(2),e?2:8):K.test(t)?NaN:+t},Y=function(t,e){return D(o(t,e,n),t+"")}((function(n,e,r){return t(n,X(e)||0,r)}));!function(){"use strict";const t=window.localStorage,n=document.documentElement,e=window.matchMedia("(prefers-color-scheme: dark)");function r(){const n=null!==t?t.getItem("theme"):null;return n?"dark"===n:e.matches}function o(){this.checked?(Y((function(){n.classList.add("dark-theme")}),100),c("dark")):(Y((function(){n.classList.remove("dark-theme")}),100),c("light"))}function c(n){t&&t.setItem("theme",n)}r()&&n.classList.add("dark-theme"),window.addEventListener("load",(function(){const t=document.querySelector("#switch-theme-checkbox");t.checked=r(),t.addEventListener("change",o.bind(t))}))}()}(); +//# sourceMappingURL=setup.js.map diff --git a/applications/rest-service/src/main/resources/static/js/site.js b/applications/spring-boot-upgrade/src/main/resources/static/js/site.js similarity index 100% rename from applications/rest-service/src/main/resources/static/js/site.js rename to applications/spring-boot-upgrade/src/main/resources/static/js/site.js diff --git a/applications/rest-service/src/main/resources/static/js/site.js.map b/applications/spring-boot-upgrade/src/main/resources/static/js/site.js.map similarity index 100% rename from applications/rest-service/src/main/resources/static/js/site.js.map rename to applications/spring-boot-upgrade/src/main/resources/static/js/site.js.map diff --git a/applications/spring-boot-upgrade/src/main/resources/static/js/site2.js b/applications/spring-boot-upgrade/src/main/resources/static/js/site2.js new file mode 100644 index 000000000..e4fc71fe8 --- /dev/null +++ b/applications/spring-boot-upgrade/src/main/resources/static/js/site2.js @@ -0,0 +1,7 @@ +!function(){"use strict";function n(){const n=document.getElementById("anchor-rewrite"),o=window.location.hash.substr(1);n&&o&&function(n,o){const e=[n];for(console.debug(n);o[n];){if(n=o[n],e.includes(n))return void console.error("Skipping circular anchor update");e.push(n)}window.location.hash=n}(o,JSON.parse(n.innerHTML))}window.addEventListener("load",n),window.addEventListener("hashchange",n)}(); +!function(){"use strict";!function(){let t=document.getElementById("author"),n=t;for(;t;)t.classList.contains("author")&&(n=t),t=t.nextElementSibling;n&&n.classList.add("last-author")}()}(); +!function(){var t=function(t,n,e){if("function"!=typeof t)throw new TypeError("Expected a function");return setTimeout((function(){t.apply(void 0,e)}),n)};var n=function(t){return t};var e=function(t,n,e){switch(e.length){case 0:return t.call(n);case 1:return t.call(n,e[0]);case 2:return t.call(n,e[0],e[1]);case 3:return t.call(n,e[0],e[1],e[2])}return t.apply(n,e)},r=Math.max;var o=function(t,n,o){return n=r(void 0===n?t.length-1:n,0),function(){for(var c=arguments,i=-1,u=r(c.length-n,0),a=Array(u);++i0){if(++n>=800)return arguments[0]}else n=0;return t.apply(void 0,arguments)}},G=D(I);var M=/\s/;var U=function(t){for(var n=t.length;n--&&M.test(t.charAt(n)););return n},z=/^\s+/;var B=function(t){return t?t.slice(0,U(t)+1).replace(z,""):t};var H=function(t){return null!=t&&"object"==typeof t};var J=function(t){return"symbol"==typeof t||H(t)&&"[object Symbol]"==g(t)},K=/^[-+]0x[0-9a-f]+$/i,Q=/^0b[01]+$/i,V=/^0o[0-7]+$/i,W=parseInt;var X=function(t){if("number"==typeof t)return t;if(J(t))return NaN;if(m(t)){var n="function"==typeof t.valueOf?t.valueOf():t;t=m(n)?n+"":n}if("string"!=typeof t)return 0===t?t:+t;t=B(t);var e=Q.test(t);return e||V.test(t)?W(t.slice(2),e?2:8):K.test(t)?NaN:+t},Y=function(t,e){return G(o(t,e,n),t+"")}((function(n,e,r){return t(n,X(e)||0,r)}));!function(){"use strict";function t(t){const e=t.querySelector("code").cloneNode(!0);for(const t of e.querySelectorAll(".hide-when-unfolded"))t.parentNode.removeChild(t);const r=e.innerText;r&&window.navigator.clipboard.writeText(r+"\n").then(n.bind(this))}function n(){this.classList.add("clicked")}function e(){this.classList.remove("clicked")}function r(t){const n=t.querySelector("code"),e=!n.classList.contains("unfolded");n.classList.remove(e?"folding":"unfolding"),n.classList.add(e?"unfolding":"folding"),Y((function(){n.classList.remove(e?"unfolding":"folding"),n.classList.toggle("unfolded")}),1100),o(this,!e)}function o(t,n){const e=n?"Expanded folded text":"Collapse foldable text";t.classList.remove(n?"fold-button":"unfold-button"),t.classList.add(n?"unfold-button":"fold-button"),t.querySelector("span.label").innerText=e,t.title=e}!function(){for(const t of document.querySelectorAll(".doc pre.highlight")){const e=document.createElement("div");e.className="codetools",n(t,e)&&t.appendChild(e)}function n(n,i){let u=0;return function(t){return!!t.querySelector("span.hide-when-folded")}(n)&&(!function(t,n){const e=c();o(e,!0),e.addEventListener("click",r.bind(e,t)),n.appendChild(e)}(n,i),u++),window.navigator.clipboard&&(!function(n,r){const o=c("Copy to clipboard","copy-button");o.addEventListener("click",t.bind(o,n)),o.addEventListener("mouseleave",e.bind(o)),o.addEventListener("blur",e.bind(o));const i=document.createElement("span");o.appendChild(i),i.className="copied",r.appendChild(o)}(n,i),u++),u>0}function c(t,n){const e=document.createElement("button");e.className=n,e.title=t,e.type="button";const r=document.createElement("span");return r.appendChild(document.createTextNode(t)),r.className="label",e.appendChild(r),e}}()}()}(); +!function(){function e(n){return n instanceof Map?n.clear=n.delete=n.set=function(){throw new Error("map is read-only")}:n instanceof Set&&(n.add=n.clear=n.delete=function(){throw new Error("set is read-only")}),Object.freeze(n),Object.getOwnPropertyNames(n).forEach((function(t){var a=n[t];"object"!=typeof a||Object.isFrozen(a)||e(a)})),n}var n=e,t=e;n.default=t;class a{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function i(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function r(e,...n){const t=Object.create(null);for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}const s=e=>!!e.kind;class o{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=i(e)}openNode(e){if(!s(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){s(e)&&(this.buffer+="")}value(){return this.buffer}span(e){this.buffer+=``}}class l{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach((n=>this._walk(e,n))),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{l._collapse(e)})))}}class c extends l{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new o(this,this.options).value()}finalize(){return!0}}function g(e){return e?"string"==typeof e?e:e.source:null}const d=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;const u="[a-zA-Z]\\w*",b="[a-zA-Z_]\\w*",m="\\b\\d+(\\.\\d+)?",h="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",f="\\b(0b[01]+)",p={begin:"\\\\[\\s\\S]",relevance:0},_={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[p]},E={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[p]},v={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},N=function(e,n,t={}){const a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(v),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},y=N("//","$"),w=N("/\\*","\\*/"),x=N("#","$"),O={className:"number",begin:m,relevance:0},M={className:"number",begin:h,relevance:0},k={className:"number",begin:f,relevance:0},R={className:"number",begin:m+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},A={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[p,{begin:/\[/,end:/\]/,relevance:0,contains:[p]}]}]},S={className:"title",begin:u,relevance:0},T={className:"title",begin:b,relevance:0},C={begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0};var D=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:u,UNDERSCORE_IDENT_RE:b,NUMBER_RE:m,C_NUMBER_RE:h,BINARY_NUMBER_RE:f,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map((e=>g(e))).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:p,APOS_STRING_MODE:_,QUOTE_STRING_MODE:E,PHRASAL_WORDS_MODE:v,COMMENT:N,C_LINE_COMMENT_MODE:y,C_BLOCK_COMMENT_MODE:w,HASH_COMMENT_MODE:x,NUMBER_MODE:O,C_NUMBER_MODE:M,BINARY_NUMBER_MODE:k,CSS_NUMBER_MODE:R,REGEXP_MODE:A,TITLE_MODE:S,UNDERSCORE_TITLE_MODE:T,METHOD_GUARD:C,END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}});function L(e,n){"."===e.input[e.index-1]&&n.ignoreMatch()}function B(e,n){n&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=L,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,void 0===e.relevance&&(e.relevance=0))}function $(e,n){Array.isArray(e.illegal)&&(e.illegal=function(...e){return"("+e.map((e=>g(e))).join("|")+")"}(...e.illegal))}function I(e,n){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function j(e,n){void 0===e.relevance&&(e.relevance=1)}const z=["of","and","for","in","not","or","if","then","parent","list","value"];function P(e,n,t="keyword"){const a={};return"string"==typeof e?i(t,e.split(" ")):Array.isArray(e)?i(t,e):Object.keys(e).forEach((function(t){Object.assign(a,P(e[t],n,t))})),a;function i(e,t){n&&(t=t.map((e=>e.toLowerCase()))),t.forEach((function(n){const t=n.split("|");a[t[0]]=[e,U(t[0],t[1])]}))}}function U(e,n){return n?Number(n):function(e){return z.includes(e.toLowerCase())}(e)?0:1}function K(e,{plugins:n}){function t(n,t){return new RegExp(g(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class a{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return new RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map((e=>e[1]));this.matcherRe=t(function(e,n="|"){let t=0;return e.map((e=>{t+=1;const n=t;let a=g(e),i="";for(;a.length>0;){const e=d.exec(a);if(!e){i+=a;break}i+=a.substring(0,e.index),a=a.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?i+="\\"+String(Number(e[1])+n):(i+=e[0],"("===e[0]&&t++)}return i})).map((e=>`(${e})`)).join(n)}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex(((e,n)=>n>0&&void 0!==e)),a=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,a)}}class i{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new a;return this.rules.slice(e).forEach((([e,t])=>n.addRule(e,t))),n.compile(),this.multiRegexes[e]=n,n}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;let t=n.exec(e);if(this.resumingScanAtSamePosition())if(t&&t.index===this.lastIndex);else{const n=this.getMatcher(0);n.lastIndex=this.lastIndex+1,t=n.exec(e)}return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&this.considerAll()),t}}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=r(e.classNameAliases||{}),function n(a,s){const o=a;if(a.isCompiled)return o;[I].forEach((e=>e(a,s))),e.compilerExtensions.forEach((e=>e(a,s))),a.__beforeBegin=null,[B,$,j].forEach((e=>e(a,s))),a.isCompiled=!0;let l=null;if("object"==typeof a.keywords&&(l=a.keywords.$pattern,delete a.keywords.$pattern),a.keywords&&(a.keywords=P(a.keywords,e.case_insensitive)),a.lexemes&&l)throw new Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l=l||a.lexemes||/\w+/,o.keywordPatternRe=t(l,!0),s&&(a.begin||(a.begin=/\B|\b/),o.beginRe=t(a.begin),a.endSameAsBegin&&(a.end=a.begin),a.end||a.endsWithParent||(a.end=/\B|\b/),a.end&&(o.endRe=t(a.end)),o.terminatorEnd=g(a.end)||"",a.endsWithParent&&s.terminatorEnd&&(o.terminatorEnd+=(a.end?"|":"")+s.terminatorEnd)),a.illegal&&(o.illegalRe=t(a.illegal)),a.contains||(a.contains=[]),a.contains=[].concat(...a.contains.map((function(e){return function(e){e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((function(n){return r(e,{variants:null},n)})));if(e.cachedVariants)return e.cachedVariants;if(H(e))return r(e,{starts:e.starts?r(e.starts):null});if(Object.isFrozen(e))return r(e);return e}("self"===e?a:e)}))),a.contains.forEach((function(e){n(e,o)})),a.starts&&n(a.starts,s),o.matcher=function(e){const n=new i;return e.contains.forEach((e=>n.addRule(e.begin,{rule:e,type:"begin"}))),e.terminatorEnd&&n.addRule(e.terminatorEnd,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(o),o}(e)}function H(e){return!!e&&(e.endsWithParent||H(e.starts))}function Z(e){const n={props:["language","code","autodetect"],data:function(){return{detectedLanguage:"",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!e.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),this.unknownLanguage=!0,i(this.code);let n={};return this.autoDetect?(n=e.highlightAuto(this.code),this.detectedLanguage=n.language):(n=e.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),n.value},autoDetect(){return!this.language||(e=this.autodetect,Boolean(e||""===e));var e},ignoreIllegals:()=>!0},render(e){return e("pre",{},[e("code",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:n,VuePlugin:{install(e){e.component("highlightjs",n)}}}}const G={"after:highlightElement":({el:e,result:n,text:t})=>{const a=q(e);if(!a.length)return;const r=document.createElement("div");r.innerHTML=n.value,n.value=function(e,n,t){let a=0,r="";const s=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function c(e){r+=""}function g(e){("start"===e.event?l:c)(e.node)}for(;e.length||n.length;){let n=o();if(r+=i(t.substring(a,n[0].offset)),a=n[0].offset,n===e){s.reverse().forEach(c);do{g(n.splice(0,1)[0]),n=o()}while(n===e&&n.length&&n[0].offset===a);s.reverse().forEach(l)}else"start"===n[0].event?s.push(n[0].node):s.pop(),g(n.splice(0,1)[0])}return r+i(t.substr(a))}(a,q(r),t)}};function F(e){return e.nodeName.toLowerCase()}function q(e){const n=[];return function e(t,a){for(let i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=e(i,a),F(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}const W={},Q=e=>{console.error(e)},X=(e,...n)=>{console.log(`WARN: ${e}`,...n)},V=(e,n)=>{W[`${e}/${n}`]||(console.log(`Deprecated as of ${e}. ${n}`),W[`${e}/${n}`]=!0)},J=i,Y=r,ee=Symbol("nomatch");var ne=function(e){const t=Object.create(null),i=Object.create(null),r=[];let s=!0;const o=/(^(<[^>]+>|\t|)+|\n)/gm,l="Could not find the language '{}', did you forget to load/include a language module?",g={disableAutodetect:!0,name:"Plain text",contains:[]};let d={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:c};function u(e){return d.noHighlightRe.test(e)}function b(e,n,t,a){let i="",r="";"object"==typeof n?(i=e,t=n.ignoreIllegals,r=n.language,a=void 0):(V("10.7.0","highlight(lang, code, ...args) has been deprecated."),V("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),r=e,i=n);const s={code:i,language:r};M("before:highlight",s);const o=s.result?s.result:m(s.language,s.code,t,a);return o.code=s.code,M("after:highlight",o),o}function m(e,n,i,o){function c(e,n){const t=N.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function g(){null!=O.subLanguage?function(){if(""===R)return;let e=null;if("string"==typeof O.subLanguage){if(!t[O.subLanguage])return void k.addText(R);e=m(O.subLanguage,R,!0,M[O.subLanguage]),M[O.subLanguage]=e.top}else e=h(R,O.subLanguage.length?O.subLanguage:null);O.relevance>0&&(A+=e.relevance),k.addSublanguage(e.emitter,e.language)}():function(){if(!O.keywords)return void k.addText(R);let e=0;O.keywordPatternRe.lastIndex=0;let n=O.keywordPatternRe.exec(R),t="";for(;n;){t+=R.substring(e,n.index);const a=c(O,n);if(a){const[e,i]=a;if(k.addText(t),t="",A+=i,e.startsWith("_"))t+=n[0];else{const t=N.classNameAliases[e]||e;k.addKeyword(n[0],t)}}else t+=n[0];e=O.keywordPatternRe.lastIndex,n=O.keywordPatternRe.exec(R)}t+=R.substr(e),k.addText(t)}(),R=""}function u(e){return e.className&&k.openNode(N.classNameAliases[e.className]||e.className),O=Object.create(e,{parent:{value:O}}),O}function b(e,n,t){let i=function(e,n){const t=e&&e.exec(n);return t&&0===t.index}(e.endRe,t);if(i){if(e["on:end"]){const t=new a(e);e["on:end"](n,t),t.isMatchIgnored&&(i=!1)}if(i){for(;e.endsParent&&e.parent;)e=e.parent;return e}}if(e.endsWithParent)return b(e.parent,n,t)}function f(e){return 0===O.matcher.regexIndex?(R+=e[0],1):(C=!0,0)}function p(e){const n=e[0],t=e.rule,i=new a(t),r=[t.__beforeBegin,t["on:begin"]];for(const t of r)if(t&&(t(e,i),i.isMatchIgnored))return f(n);return t&&t.endSameAsBegin&&(t.endRe=new RegExp(n.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),t.skip?R+=n:(t.excludeBegin&&(R+=n),g(),t.returnBegin||t.excludeBegin||(R=n)),u(t),t.returnBegin?0:n.length}function _(e){const t=e[0],a=n.substr(e.index),i=b(O,e,a);if(!i)return ee;const r=O;r.skip?R+=t:(r.returnEnd||r.excludeEnd||(R+=t),g(),r.excludeEnd&&(R=t));do{O.className&&k.closeNode(),O.skip||O.subLanguage||(A+=O.relevance),O=O.parent}while(O!==i.parent);return i.starts&&(i.endSameAsBegin&&(i.starts.endRe=i.endRe),u(i.starts)),r.returnEnd?0:t.length}let E={};function v(t,a){const r=a&&a[0];if(R+=t,null==r)return g(),0;if("begin"===E.type&&"end"===a.type&&E.index===a.index&&""===r){if(R+=n.slice(a.index,a.index+1),!s){const n=new Error("0 width match regex");throw n.languageName=e,n.badRule=E.rule,n}return 1}if(E=a,"begin"===a.type)return p(a);if("illegal"===a.type&&!i){const e=new Error('Illegal lexeme "'+r+'" for mode "'+(O.className||"")+'"');throw e.mode=O,e}if("end"===a.type){const e=_(a);if(e!==ee)return e}if("illegal"===a.type&&""===r)return 1;if(T>1e5&&T>3*a.index){throw new Error("potential infinite loop, way more iterations than matches")}return R+=r,r.length}const N=w(e);if(!N)throw Q(l.replace("{}",e)),new Error('Unknown language: "'+e+'"');const y=K(N,{plugins:r});let x="",O=o||y;const M={},k=new d.__emitter(d);!function(){const e=[];for(let n=O;n!==N;n=n.parent)n.className&&e.unshift(n.className);e.forEach((e=>k.openNode(e)))}();let R="",A=0,S=0,T=0,C=!1;try{for(O.matcher.considerAll();;){T++,C?C=!1:O.matcher.considerAll(),O.matcher.lastIndex=S;const e=O.matcher.exec(n);if(!e)break;const t=v(n.substring(S,e.index),e);S=e.index+t}return v(n.substr(S)),k.closeAllNodes(),k.finalize(),x=k.toHTML(),{relevance:Math.floor(A),value:x,language:e,illegal:!1,emitter:k,top:O}}catch(t){if(t.message&&t.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:t.message,context:n.slice(S-100,S+100),mode:t.mode},sofar:x,relevance:0,value:J(n),emitter:k};if(s)return{illegal:!1,relevance:0,value:J(n),emitter:k,language:e,top:O,errorRaised:t};throw t}}function h(e,n){n=n||d.languages||Object.keys(t);const a=function(e){const n={relevance:0,emitter:new d.__emitter(d),value:J(e),illegal:!1,top:g};return n.emitter.addText(e),n}(e),i=n.filter(w).filter(O).map((n=>m(n,e,!1)));i.unshift(a);const r=i.sort(((e,n)=>{if(e.relevance!==n.relevance)return n.relevance-e.relevance;if(e.language&&n.language){if(w(e.language).supersetOf===n.language)return 1;if(w(n.language).supersetOf===e.language)return-1}return 0})),[s,o]=r,l=s;return l.second_best=o,l}const f={"before:highlightElement":({el:e})=>{d.useBR&&(e.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"))},"after:highlightElement":({result:e})=>{d.useBR&&(e.value=e.value.replace(/\n/g,"
"))}},p=/^(<[^>]+>|\t)+/gm,_={"after:highlightElement":({result:e})=>{d.tabReplace&&(e.value=e.value.replace(p,(e=>e.replace(/\t/g,d.tabReplace))))}};function E(e){let n=null;const t=function(e){let n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=d.languageDetectRe.exec(n);if(t){const n=w(t[1]);return n||(X(l.replace("{}",t[1])),X("Falling back to no-highlight mode for this block.",e)),n?t[1]:"no-highlight"}return n.split(/\s+/).find((e=>u(e)||w(e)))}(e);if(u(t))return;M("before:highlightElement",{el:e,language:t}),n=e;const a=n.textContent,r=t?b(a,{language:t,ignoreIllegals:!0}):h(a);M("after:highlightElement",{el:e,result:r,text:a}),e.innerHTML=r.value,function(e,n,t){const a=n?i[n]:t;e.classList.add("hljs"),a&&e.classList.add(a)}(e,t,r.language),e.result={language:r.language,re:r.relevance,relavance:r.relevance},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.relevance,relavance:r.second_best.relevance})}const v=()=>{if(v.called)return;v.called=!0,V("10.6.0","initHighlighting() is deprecated. Use highlightAll() instead.");document.querySelectorAll("pre code").forEach(E)};let N=!1;function y(){if("loading"===document.readyState)return void(N=!0);document.querySelectorAll("pre code").forEach(E)}function w(e){return e=(e||"").toLowerCase(),t[e]||t[i[e]]}function x(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach((e=>{i[e.toLowerCase()]=n}))}function O(e){const n=w(e);return n&&!n.disableAutodetect}function M(e,n){const t=e;r.forEach((function(e){e[t]&&e[t](n)}))}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(function(){N&&y()}),!1),Object.assign(e,{highlight:b,highlightAuto:h,highlightAll:y,fixMarkup:function(e){return V("10.2.0","fixMarkup will be removed entirely in v11.0"),V("10.2.0","Please see https://github.com/highlightjs/highlight.js/issues/2534"),n=e,d.tabReplace||d.useBR?n.replace(o,(e=>"\n"===e?d.useBR?"
":e:d.tabReplace?e.replace(/\t/g,d.tabReplace):e)):n;var n},highlightElement:E,highlightBlock:function(e){return V("10.7.0","highlightBlock will be removed entirely in v12.0"),V("10.7.0","Please use highlightElement now."),E(e)},configure:function(e){e.useBR&&(V("10.3.0","'useBR' will be removed entirely in v11.0"),V("10.3.0","Please see https://github.com/highlightjs/highlight.js/issues/2559")),d=Y(d,e)},initHighlighting:v,initHighlightingOnLoad:function(){V("10.6.0","initHighlightingOnLoad() is deprecated. Use highlightAll() instead."),N=!0},registerLanguage:function(n,a){let i=null;try{i=a(e)}catch(e){if(Q("Language definition for '{}' could not be registered.".replace("{}",n)),!s)throw e;Q(e),i=g}i.name||(i.name=n),t[n]=i,i.rawDefinition=a.bind(null,e),i.aliases&&x(i.aliases,{languageName:n})},unregisterLanguage:function(e){delete t[e];for(const n of Object.keys(i))i[n]===e&&delete i[n]},listLanguages:function(){return Object.keys(t)},getLanguage:w,registerAliases:x,requireLanguage:function(e){V("10.4.0","requireLanguage will be removed entirely in v11."),V("10.4.0","Please see https://github.com/highlightjs/highlight.js/pull/2844");const n=w(e);if(n)return n;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:O,inherit:Y,addPlugin:function(e){!function(e){e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=n=>{e["before:highlightBlock"](Object.assign({block:n.el},n))}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=n=>{e["after:highlightBlock"](Object.assign({block:n.el},n))})}(e),r.push(e)},vuePlugin:Z(e).VuePlugin}),e.debugMode=function(){s=!1},e.safeMode=function(){s=!0},e.versionString="10.7.3";for(const e in D)"object"==typeof D[e]&&n(D[e]);return Object.assign(e,D),e.addPlugin(f),e.addPlugin(G),e.addPlugin(_),e}({});function te(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var ae=function(e){const n=[{className:"strong",begin:/\*{2}([^\n]+?)\*{2}/},{className:"strong",begin:te(/\*\*/,/((\*(?!\*)|\\[^\n]|[^*\n\\])+\n)+/,/(\*(?!\*)|\\[^\n]|[^*\n\\])*/,/\*\*/),relevance:0},{className:"strong",begin:/\B\*(\S|\S[^\n]*?\S)\*(?!\w)/},{className:"strong",begin:/\*[^\s]([^\n]+\n)+([^\n]+)\*/}],t=[{className:"emphasis",begin:/_{2}([^\n]+?)_{2}/},{className:"emphasis",begin:te(/__/,/((_(?!_)|\\[^\n]|[^_\n\\])+\n)+/,/(_(?!_)|\\[^\n]|[^_\n\\])*/,/__/),relevance:0},{className:"emphasis",begin:/\b_(\S|\S[^\n]*?\S)_(?!\w)/},{className:"emphasis",begin:/_[^\s]([^\n]+\n)+([^\n]+)_/},{className:"emphasis",begin:"\\B'(?!['\\s])",end:"(\\n{2}|')",contains:[{begin:"\\\\'\\w",relevance:0}],relevance:0}];return{name:"AsciiDoc",aliases:["adoc"],contains:[e.COMMENT("^/{4,}\\n","\\n/{4,}$",{relevance:10}),e.COMMENT("^//","$",{relevance:0}),{className:"title",begin:"^\\.\\w.*$"},{begin:"^[=\\*]{4,}\\n",end:"\\n^[=\\*]{4,}$",relevance:10},{className:"section",relevance:10,variants:[{begin:"^(={1,6})[ \t].+?([ \t]\\1)?$"},{begin:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{className:"meta",begin:"^:.+?:",end:"\\s",excludeEnd:!0,relevance:10},{className:"meta",begin:"^\\[.+?\\]$",relevance:0},{className:"quote",begin:"^_{4,}\\n",end:"\\n_{4,}$",relevance:10},{className:"code",begin:"^[\\-\\.]{4,}\\n",end:"\\n[\\-\\.]{4,}$",relevance:10},{begin:"^\\+{4,}\\n",end:"\\n\\+{4,}$",contains:[{begin:"<",end:">",subLanguage:"xml",relevance:0}],relevance:10},{className:"bullet",begin:"^(\\*+|-+|\\.+|[^\\n]+?::)\\s+"},{className:"symbol",begin:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",relevance:10},{begin:/\\[*_`]/},{begin:/\\\\\*{2}[^\n]*?\*{2}/},{begin:/\\\\_{2}[^\n]*_{2}/},{begin:/\\\\`{2}[^\n]*`{2}/},{begin:/[:;}][*_`](?![*_`])/},...n,...t,{className:"string",variants:[{begin:"``.+?''"},{begin:"`.+?'"}]},{className:"code",begin:/`{2}/,end:/(\n{2}|`{2})/},{className:"code",begin:"(`.+?`|\\+.+?\\+)",relevance:0},{className:"code",begin:"^[ \\t]",end:"$",relevance:0},{begin:"^'{3,}[ \\t]*$",relevance:10},{begin:"(link:)?(http|https|ftp|file|irc|image:?):\\S+?\\[[^[]*?\\]",returnBegin:!0,contains:[{begin:"(link|image:?):",relevance:0},{className:"link",begin:"\\w",end:"[^\\[]+",relevance:0},{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0,relevance:0}],relevance:10}]}};function ie(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var re=function(e){const n={},t={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[n]}]};Object.assign(n,{className:"variable",variants:[{begin:ie(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},t]});const a={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},i={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},r={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n,a]};a.contains.push(r);const s={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,n]},o=e.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),l={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[o,e.SHEBANG(),l,s,e.HASH_COMMENT_MODE,i,r,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},n]}};const se=["a","abbr","address","article","aside","audio","b","blockquote","body","button","canvas","caption","cite","code","dd","del","details","dfn","div","dl","dt","em","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","html","i","iframe","img","input","ins","kbd","label","legend","li","main","mark","menu","nav","object","ol","p","q","quote","samp","section","span","strong","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","tr","ul","var","video"],oe=["any-hover","any-pointer","aspect-ratio","color","color-gamut","color-index","device-aspect-ratio","device-height","device-width","display-mode","forced-colors","grid","height","hover","inverted-colors","monochrome","orientation","overflow-block","overflow-inline","pointer","prefers-color-scheme","prefers-contrast","prefers-reduced-motion","prefers-reduced-transparency","resolution","scan","scripting","update","width","min-width","max-width","min-height","max-height"],le=["active","any-link","blank","checked","current","default","defined","dir","disabled","drop","empty","enabled","first","first-child","first-of-type","fullscreen","future","focus","focus-visible","focus-within","has","host","host-context","hover","indeterminate","in-range","invalid","is","lang","last-child","last-of-type","left","link","local-link","not","nth-child","nth-col","nth-last-child","nth-last-col","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","past","placeholder-shown","read-only","read-write","required","right","root","scope","target","target-within","user-invalid","valid","visited","where"],ce=["after","backdrop","before","cue","cue-region","first-letter","first-line","grammar-error","marker","part","placeholder","selection","slotted","spelling-error"],ge=["align-content","align-items","align-self","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","auto","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","clear","clip","clip-path","color","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-display","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-smoothing","font-stretch","font-style","font-variant","font-variant-ligatures","font-variation-settings","font-weight","height","hyphens","icon","image-orientation","image-rendering","image-resolution","ime-mode","inherit","initial","justify-content","left","letter-spacing","line-height","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","mask","max-height","max-width","min-height","min-width","nav-down","nav-index","nav-left","nav-right","nav-up","none","normal","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","perspective","perspective-origin","pointer-events","position","quotes","resize","right","src","tab-size","table-layout","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-overflow","text-rendering","text-shadow","text-transform","text-underline-position","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","white-space","widows","width","word-break","word-spacing","word-wrap","z-index"].reverse();function de(e){return function(...e){return e.map((e=>function(e){return e?"string"==typeof e?e:e.source:null}(e))).join("")}("(?=",e,")")}var ue=function(e){const n=(e=>({IMPORTANT:{className:"meta",begin:"!important"},HEXCOLOR:{className:"number",begin:"#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})"},ATTRIBUTE_SELECTOR_MODE:{className:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]}}))(e),t=[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE];return{name:"CSS",case_insensitive:!0,illegal:/[=|'\$]/,keywords:{keyframePosition:"from to"},classNameAliases:{keyframePosition:"selector-tag"},contains:[e.C_BLOCK_COMMENT_MODE,{begin:/-(webkit|moz|ms|o)-(?=[a-z])/},e.CSS_NUMBER_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/,relevance:0},{className:"selector-class",begin:"\\.[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},n.ATTRIBUTE_SELECTOR_MODE,{className:"selector-pseudo",variants:[{begin:":("+le.join("|")+")"},{begin:"::("+ce.join("|")+")"}]},{className:"attribute",begin:"\\b("+ge.join("|")+")\\b"},{begin:":",end:"[;}]",contains:[n.HEXCOLOR,n.IMPORTANT,e.CSS_NUMBER_MODE,...t,{begin:/(url|data-uri)\(/,end:/\)/,relevance:0,keywords:{built_in:"url data-uri"},contains:[{className:"string",begin:/[^)]/,endsWithParent:!0,excludeEnd:!0}]},{className:"built_in",begin:/[\w-]+(?=\()/}]},{begin:de(/@/),end:"[{;]",relevance:0,illegal:/:/,contains:[{className:"keyword",begin:/@-?\w[\w]*(-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:{$pattern:/[a-z-]+/,keyword:"and or not only",attribute:oe.join(" ")},contains:[{begin:/[a-z-]+(?=:)/,className:"attribute"},...t,e.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"\\b("+se.join("|")+")\\b"}]}};var be=function(e){return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,variants:[{begin:/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/},{begin:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{begin:/^--- +\d+,\d+ +----$/}]},{className:"comment",variants:[{begin:/Index: /,end:/$/},{begin:/^index/,end:/$/},{begin:/={3,}/,end:/$/},{begin:/^-{3}/,end:/$/},{begin:/^\*{3} /,end:/$/},{begin:/^\+{3}/,end:/$/},{begin:/^\*{15}$/},{begin:/^diff --git/,end:/$/}]},{className:"addition",begin:/^\+/,end:/$/},{className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,end:/$/}]}};var me=function(e){return{name:"Dockerfile",aliases:["docker"],case_insensitive:!0,keywords:"from maintainer expose env arg user onbuild stopsignal",contains:[e.HASH_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{beginKeywords:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{end:/[^\\]$/,subLanguage:"bash"}}],illegal:"function(e){return e?"string"==typeof e?e:e.source:null}(e))).join("")}("(?=",e,")")}function pe(e,n={}){return n.variants=e,n}var _e=function(e){const n="[A-Za-z0-9_$]+",t=pe([e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]})]),a={className:"regexp",begin:/~?\/[^\/\n]+\//,contains:[e.BACKSLASH_ESCAPE]},i=pe([e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]),r=pe([{begin:/"""/,end:/"""/},{begin:/'''/,end:/'''/},{begin:"\\$/",end:"/\\$",relevance:10},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE],{className:"string"});return{name:"Groovy",keywords:{built_in:"this super",literal:"true false null",keyword:"byte short char int long boolean float double void def as in assert trait abstract static volatile transient public private protected synchronized final class interface enum if else for while switch case break default continue throw throws try catch finally implements extends new import package return instanceof"},contains:[e.SHEBANG({binary:"groovy",relevance:10}),t,r,a,i,{className:"class",beginKeywords:"class interface trait enum",end:/\{/,illegal:":",contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{className:"meta",begin:"@[A-Za-z]+",relevance:0},{className:"attr",begin:n+"[ \t]*:",relevance:0},{begin:/\?/,end:/:/,relevance:0,contains:[t,r,a,i,"self"]},{className:"symbol",begin:"^[ \t]*"+fe(n+":"),excludeBegin:!0,end:n+":",relevance:0}],illegal:/#|<\//}};function Ee(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var ve=function(e){const n="HTTP/(2|1\\.[01])",t={className:"attribute",begin:Ee("^",/[A-Za-z][A-Za-z0-9-]*/,"(?=\\:\\s)"),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},a=[t,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+n+" \\d{3})",end:/$/,contains:[{className:"meta",begin:n},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:a}},{begin:"(?=^[A-Z]+ (.*?) "+n+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:n},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:a}},e.inherit(t,{relevance:0})]}},Ne="\\.([0-9](_*[0-9])*)",ye="[0-9a-fA-F](_*[0-9a-fA-F])*",we={className:"number",variants:[{begin:`(\\b([0-9](_*[0-9])*)((${Ne})|\\.)?|(${Ne}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:`\\b([0-9](_*[0-9])*)((${Ne})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${Ne})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{begin:`\\b0[xX]((${ye})\\.?|(${ye})?\\.(${ye}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${ye})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};var xe=function(e){var n="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",a={className:"meta",begin:"@"+n,contains:[{begin:/\(/,end:/\)/,contains:["self"]}]};const i=we;return{name:"Java",aliases:["jsp"],keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{begin:/import java\.[a-z]+\./,keywords:"import",relevance:2},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface enum",end:/[{;=]/,excludeEnd:!0,relevance:1,keywords:"class interface enum",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"class",begin:"record\\s+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,excludeEnd:!0,end:/[{;=]/,keywords:t,contains:[{beginKeywords:"record"},{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[a,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,i,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},i,a]}};const Oe="[A-Za-z$_][0-9A-Za-z$_]*",Me=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],ke=["true","false","null","undefined","NaN","Infinity"],Re=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer","BigInt64Array","BigUint64Array","BigInt"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function Ae(e){return Se("(?=",e,")")}function Se(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Te=function(e){const n=Oe,t="<>",a="",i={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{const t=e[0].length+e.index,a=e.input[t];"<"!==a?">"===a&&(((e,{after:n})=>{const t="",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:r,contains:f}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:t,end:a},{begin:i.begin,"on:begin":i.isTrulyOpeningTag,end:i.end}],subLanguage:"xml",contains:[{begin:i.begin,end:i.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[{;]/,excludeEnd:!0,keywords:r,contains:["self",e.inherit(e.TITLE_MODE,{begin:n}),p],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[p,e.inherit(e.TITLE_MODE,{begin:n})]},{variants:[{begin:"\\."+n},{begin:"\\$"+n}],relevance:0},{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"[\]]/,contains:[{beginKeywords:"extends"},e.UNDERSCORE_TITLE_MODE]},{begin:/\b(?=constructor)/,end:/[{;]/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:n}),"self",p]},{begin:"(get|set)\\s+(?="+n+"\\()",end:/\{/,keywords:"get set",contains:[e.inherit(e.TITLE_MODE,{begin:n}),{begin:/\(\)/},p]},{begin:/\$[(.]/}]}};var Ce=function(e){const n={literal:"true false null"},t=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],a=[e.QUOTE_STRING_MODE,e.C_NUMBER_MODE],i={end:",",endsWithParent:!0,excludeEnd:!0,contains:a,keywords:n},r={begin:/\{/,end:/\}/,contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(i,{begin:/:/})].concat(t),illegal:"\\S"},s={begin:"\\[",end:"\\]",contains:[e.inherit(i)],illegal:"\\S"};return a.push(r,s),t.forEach((function(e){a.push(e)})),{name:"JSON",contains:a,keywords:n,illegal:"\\S"}},De="\\.([0-9](_*[0-9])*)",Le="[0-9a-fA-F](_*[0-9a-fA-F])*",Be={className:"number",variants:[{begin:`(\\b([0-9](_*[0-9])*)((${De})|\\.)?|(${De}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:`\\b([0-9](_*[0-9])*)((${De})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${De})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{begin:`\\b0[xX]((${Le})\\.?|(${Le})?\\.(${Le}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${Le})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};var $e=function(e){const n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},t={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},a={className:"subst",begin:/\$\{/,end:/\}/,contains:[e.C_NUMBER_MODE]},i={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},r={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[i,a]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,i,a]}]};a.contains.push(r);const s={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},o={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(r,{className:"meta-string"})]}]},l=Be,c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),g={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},d=g;return d.variants[1].contains=[g],g.variants[1].contains=[d],{name:"Kotlin",aliases:["kt","kts"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},t,s,o,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[g,e.C_LINE_COMMENT_MODE,c],relevance:0},e.C_LINE_COMMENT_MODE,c,s,o,r,e.C_NUMBER_MODE]},c]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},s,o]},r,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},l]}};function Ie(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var je=function(e){const n={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},t={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,relevance:2},{begin:Ie(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/),relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{begin:/\[.+?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}]},a={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},i={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};a.contains.push(i),i.contains.push(a);let r=[n,t];return a.contains=a.contains.concat(r),i.contains=i.contains.concat(r),r=r.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:r},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:r}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:r,end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},t,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}};var ze=function(e){const n={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},t={className:"subst",begin:/\$\{/,end:/\}/,keywords:n},a={className:"string",contains:[t],variants:[{begin:"''",end:"''"},{begin:'"',end:'"'}]},i=[e.NUMBER_MODE,e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,{begin:/[a-zA-Z0-9-_]+(\s*=)/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/\S+/}]}];return t.contains=i,{name:"Nix",aliases:["nixos"],keywords:n,contains:i}};var Pe=function(e){var n="[ \\t\\f]*",t=n+"[:=]"+n,a="[ \\t\\f]+",i="("+t+"|"+"[ \\t\\f]+)",r="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",s="([^\\\\:= \\t\\f\\n]|\\\\.)+",o={end:i,relevance:0,starts:{className:"string",end:/$/,relevance:0,contains:[{begin:"\\\\\\\\"},{begin:"\\\\\\n"}]}};return{name:".properties",case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT("^\\s*[!#]","$"),{returnBegin:!0,variants:[{begin:r+t,relevance:1},{begin:r+a,relevance:0}],contains:[{className:"attr",begin:r,endsParent:!0,relevance:0}],starts:o},{begin:s+i,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:s,endsParent:!0,relevance:0}],starts:o},{className:"attr",relevance:0,begin:s+n+"$"}]}};function Ue(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ke=function(e){const n="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",t={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor __FILE__",built_in:"proc lambda",literal:"true false nil"},a={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},r=[e.COMMENT("#","$",{contains:[a]}),e.COMMENT("^=begin","^=end",{contains:[a],relevance:10}),e.COMMENT("^__END__","\\n$")],s={className:"subst",begin:/#\{/,end:/\}/,keywords:t},o={className:"string",contains:[e.BACKSLASH_ESCAPE,s],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?/},{begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{begin:/<<[-~]?'?(\w+)\n(?:[^\n]*\n)*?\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,s]})]}]},l="[0-9](_?[0-9])*",c={className:"number",relevance:0,variants:[{begin:`\\b([1-9](_?[0-9])*|0)(\\.(${l}))?([eE][+-]?(${l})|r)?i?\\b`},{begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{begin:"\\b0(_?[0-7])+r?i?\\b"}]},g={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:t},d=[o,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE,relevance:0}]}].concat(r)},{className:"function",begin:Ue(/def\s+/,(u=n+"\\s*(\\(|;|$)",Ue("(?=",u,")"))),relevance:0,keywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),g].concat(r)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[o,{begin:n}],relevance:0},c,{className:"variable",begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{className:"params",begin:/\|/,end:/\|/,relevance:0,keywords:t},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,s],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(i,r),relevance:0}].concat(i,r);var u;s.contains=d,g.contains=d;const b=[{begin:/^\s*=>/,starts:{end:"$",contains:d}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>)(?=[ ])",starts:{end:"$",contains:d}}];return r.unshift(i),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:t,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(b).concat(r).concat(d)}};var He=function(e){const n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:/\$\{/,end:/\}/}]},t={className:"string",variants:[{begin:'"""',end:'"""'},{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[n],relevance:10}]},a={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},i={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0},r={className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[a]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[a]},i]},s={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[i]};return{name:"Scala",keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},a,s,r,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}};var Ze=function(e){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#]/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}};function Ge(e){return e?"string"==typeof e?e:e.source:null}function Fe(...e){return e.map((e=>Ge(e))).join("")}function qe(...e){return"("+e.map((e=>Ge(e))).join("|")+")"}var We=function(e){const n=e.COMMENT("--","$"),t=["true","false","unknown"],a=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],i=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],r=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],s=i,o=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update ","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!i.includes(e))),l={begin:Fe(/\b/,qe(...s),/\s*\(/),keywords:{built_in:s}};return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{$pattern:/\b[\w\.]+/,keyword:function(e,{exceptions:n,when:t}={}){const a=t;return n=n||[],e.map((e=>e.match(/\|\d+$/)||n.includes(e)?e:a(e)?`${e}|0`:e))}(o,{when:e=>e.length<3}),literal:t,type:a,built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"]},contains:[{begin:qe(...r),keywords:{$pattern:/[\w\.]+/,keyword:o.concat(r),literal:t,type:a}},{className:"type",begin:qe("double precision","large object","with timezone","without timezone")},l,{className:"variable",begin:/@[a-z0-9]+/},{className:"string",variants:[{begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,contains:[{begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,n,{className:"operator",begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,relevance:0}]}};function Qe(e){return e?"string"==typeof e?e:e.source:null}function Xe(e){return Ve("(?=",e,")")}function Ve(...e){return e.map((e=>Qe(e))).join("")}function Je(...e){return"("+e.map((e=>Qe(e))).join("|")+")"}var Ye=function(e){const n=Ve(/[A-Z_]/,Ve("(",/[A-Z0-9_.-]*:/,")?"),/[A-Z0-9_.-]*/),t={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},a={begin:/\s/,contains:[{className:"meta-keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},i=e.inherit(a,{begin:/\(/,end:/\)/}),r=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),s=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),o={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin://,relevance:10,contains:[a,s,r,i,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[a,i,s,r]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},t,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[o],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[o],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:Ve(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:o}]},{className:"tag",begin:Ve(/<\//,Xe(Ve(n,/>/))),contains:[{className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}};var en=function(e){var n="true false yes no null",t="[\\w#;/?:@&=+$,.~*'()[\\]]+",a={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},i=e.inherit(a,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),r={className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},s={end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},o={begin:/\{/,end:/\}/,contains:[s],illegal:"\\n",relevance:0},l={begin:"\\[",end:"\\]",contains:[s],illegal:"\\n",relevance:0},c=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+t},{className:"type",begin:"!<"+t+">"},{className:"type",begin:"!"+t},{className:"type",begin:"!!"+t},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},r,{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},o,l,a],g=[...c];return g.pop(),g.push(i),s.contains=g,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:c}};!function(){"use strict";ne.registerLanguage("asciidoc",ae),ne.registerLanguage("bash",re),ne.registerLanguage("css",ue),ne.registerLanguage("diff",be),ne.registerLanguage("dockerfile",me),ne.registerLanguage("gradle",he),ne.registerLanguage("groovy",_e),ne.registerLanguage("http",ve),ne.registerLanguage("java",xe),ne.registerLanguage("javascript",Te),ne.registerLanguage("json",Ce),ne.registerLanguage("kotlin",$e),ne.registerLanguage("markdown",je),ne.registerLanguage("nix",ze),ne.registerLanguage("properties",Pe),ne.registerLanguage("ruby",Ke),ne.registerLanguage("scala",He),ne.registerLanguage("shell",Ze),ne.registerLanguage("bash",Ze),ne.registerLanguage("sql",We),ne.registerLanguage("xml",Ye),ne.registerLanguage("yaml",en),ne.configure({ignoreUnescapedHTML:!0});for(const e of document.querySelectorAll("pre.highlight > code"))ne.highlightBlock(e)}()}(); +!function(){"use strict";function t(t){const e=n('
');return t.prepend(e),e}function e(t,e){const o=t.querySelector(".title").textContent,c=t.querySelectorAll(".content").item(0),s=function(t,e){let n=t.nextElementSibling;for(;n;){if(n.matches(e))return n;n=n.nextElementSibling}}(t,".colist");s&&c.append(s);const r=n('
'+o+"
");return r.dataset.blockName=o,c.dataset.blockName=o,e.append(r),{tabElement:r,content:c}}function n(t){const e=document.createElement("template");return e.innerHTML=t,e.content.firstChild}function o(t){let e=t.previousElementSibling;for(;e&&!e.classList.contains("primary");)e=e.previousElementSibling;return e}function c(t){const e=this.textContent;window.localStorage.setItem(t,e);for(const n of document.querySelectorAll(".tab"))r(n)===t&&n.textContent===e&&s(n)}function s(t){for(const e of t.parentNode.children)e.classList.remove("selected");t.classList.add("selected");for(const e of t.parentNode.parentNode.children)e.classList.contains("content")&&(t.dataset.blockName===e.dataset.blockName?e.classList.remove("hidden"):e.classList.add("hidden"))}function r(t){const e=[];for(t of t.parentNode.querySelectorAll(".tab"))e.push(t.textContent.toLowerCase());return e.sort().join("-")}window.addEventListener("load",(function(){(function(){for(const n of document.querySelectorAll(".primary")){if(n.querySelector("div.switch"))return void console.debug("Skipping tabs due to existing blockswitches");e(n,t(n)).tabElement.classList.add("selected"),n.querySelector(".title").remove(),n.classList.add("tabs-content")}for(const t of document.querySelectorAll(".secondary")){const n=o(t);if(n){const o=e(t,n.querySelector(".tabs"));o.content.classList.add("hidden"),n.append(o.content),t.remove()}else console.error("Found secondary block with no primary sibling")}})(),function(){for(const t of document.querySelectorAll(".tab")){const e=r(t);t.addEventListener("click",c.bind(t,e)),t.textContent===window.localStorage.getItem(e)&&s(t)}}()}))}(); +!function(){var t=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)},e={};(function(t){(function(){var n="object"==typeof t&&t&&t.Object===Object&&t;e=n}).call(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{});var n="object"==typeof self&&self&&self.Object===Object&&self,o=e||n||Function("return this")(),r=function(){return o.Date.now()},i=/\s/;var c=function(t){for(var e=t.length;e--&&i.test(t.charAt(e)););return e},u=/^\s+/;var a=function(t){return t?t.slice(0,c(t)+1).replace(u,""):t},l=o.Symbol,f=Object.prototype,d=f.hasOwnProperty,s=f.toString,m=l?l.toStringTag:void 0;var v=function(t){var e=d.call(t,m),n=t[m];try{t[m]=void 0;var o=!0}catch(t){}var r=s.call(t);return o&&(e?t[m]=n:delete t[m]),r},p=Object.prototype.toString;var g=function(t){return p.call(t)},h=l?l.toStringTag:void 0;var y=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":h&&h in Object(t)?v(t):g(t)};var w=function(t){return null!=t&&"object"==typeof t};var E=function(t){return"symbol"==typeof t||w(t)&&"[object Symbol]"==y(t)},b=/^[-+]0x[0-9a-f]+$/i,L=/^0b[01]+$/i,j=/^0o[0-7]+$/i,x=parseInt;var S=function(e){if("number"==typeof e)return e;if(E(e))return NaN;if(t(e)){var n="function"==typeof e.valueOf?e.valueOf():e;e=t(n)?n+"":n}if("string"!=typeof e)return 0===e?e:+e;e=a(e);var o=L.test(e);return o||j.test(e)?x(e.slice(2),o?2:8):b.test(e)?NaN:+e},T=Math.max,O=Math.min;var N=function(e,n,o){var i,c,u,a,l,f,d=0,s=!1,m=!1,v=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function p(t){var n=i,o=c;return i=c=void 0,d=t,a=e.apply(o,n)}function g(t){return d=t,l=setTimeout(y,n),s?p(t):a}function h(t){var e=t-f;return void 0===f||e>=n||e<0||m&&t-d>=u}function y(){var t=r();if(h(t))return w(t);l=setTimeout(y,function(t){var e=n-(t-f);return m?O(e,u-(t-d)):e}(t))}function w(t){return l=void 0,v&&i?p(t):(i=c=void 0,a)}function E(){var t=r(),e=h(t);if(i=arguments,c=this,f=t,e){if(void 0===l)return g(f);if(m)return clearTimeout(l),l=setTimeout(y,n),p(f)}return void 0===l&&(l=setTimeout(y,n)),a}return n=S(n)||0,t(o)&&(s=!!o.leading,u=(m="maxWait"in o)?T(S(o.maxWait)||0,n):u,v="trailing"in o?!!o.trailing:v),E.cancel=function(){void 0!==l&&clearTimeout(l),d=0,i=f=c=l=void 0},E.flush=function(){return void 0===l?a:w(r())},E};var q=function(e,n,o){var r=!0,i=!0;if("function"!=typeof e)throw new TypeError("Expected a function");return t(o)&&(r="leading"in o?!!o.leading:r,i="trailing"in o?!!o.trailing:i),N(e,n,{leading:r,maxWait:n,trailing:i})};!function(){"use strict";let t,e,n,o,r,i,c=null,u=!1;function a(){v();const t=r.get(window.location.hash),e=g(window.location.hash);t&&E(e)&&(u=!0,b("activating window location hash"),y(t.parentElement)),f()}window.addEventListener("load",(function(){if(t=document.querySelector("#toc"),e=document.querySelector("#toggle-toc"),n=document.querySelector("#content"),!t||!n)return;o=function(){const e=r(),o=[];for(let t=0;t<=e;t++)o.push("h"+(t+1)+"[id]");return n.querySelectorAll(o);function r(){let e=1;for(const n of t.querySelectorAll("ul","ol"))e=Math.max(e,i(n));return e}function i(e){let n=0;for(;e&&e!==t;)n+="UL"===e.nodeName||"OL"===e.nodeName?1:0,e=e.parentElement;return e?n:-1}}(),r=function(){const e=new Map;for(const n of t.querySelectorAll("li > a")){const t=n.getAttribute("href");t&&e.set(t,n)}return e}(),i=function(){const t=new Map;for(const e of o){const n=h(e);if(n){const o=r.get(n);if(o){const n=o.parentElement;t.set(e,n)}}}return t}(),a(),window.addEventListener("hashchange",a),window.addEventListener("scroll",l),window.addEventListener("scroll",f),window.addEventListener("resize",d),t.addEventListener("click",s),e.addEventListener("click",m)}));const l=q((function(){v(),u||p()}),50,{leading:!0}),f=N((function(){if(b("scrolling ended"),v(),u=!1,c){E(g(h(c)))||p()}else p()}),50),d=q((function(){v()}),50,{leading:!0});function s(t){if("A"===t.target.nodeName){const e=t.target.parentElement;if(e&&"back-to-index"===e.id)return;u=!0,b("activating clicked toc element"),y(t.target.parentElement)}}function m(t){t.stopPropagation();document.body.classList.toggle("show-toc")?document.documentElement.addEventListener("click",m):document.documentElement.removeEventListener("click",m)}function v(){const t=window.getComputedStyle(document.documentElement),e=parseInt(t.getPropertyValue("--layout-banner-height"),10);w()>=e?document.body.classList.add("fixed-toc"):document.body.classList.remove("fixed-toc")}function p(){b("activating top header element");const t=function(){const t=w()+45;for(let e=0;et)return o[e-1>=0?e-1:0];return o[o.length-1]}();y(i.get(t))}function g(t){for(let e=0;e=0&&e.bottom<=(window.innerHeight||document.documentElement.clientHeight)}function b(t){false}}()}(); +//# sourceMappingURL=site.js.map diff --git a/applications/spring-boot-upgrade/src/test/java/org/springframework/sbm/ControllerTest.java b/applications/spring-boot-upgrade/src/test/java/org/springframework/sbm/ControllerTest.java new file mode 100644 index 000000000..f549c6b6e --- /dev/null +++ b/applications/spring-boot-upgrade/src/test/java/org/springframework/sbm/ControllerTest.java @@ -0,0 +1,74 @@ +package org.springframework.sbm;/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportRenderer; +import org.springframework.sbm.engine.commands.ApplyCommand; +import org.springframework.sbm.engine.commands.ScanCommand; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.context.ProjectContextHolder; +import org.springframework.test.web.servlet.MockMvc; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Fabian Krüger + */ +@WebMvcTest(controllers = ReportController.class) +public class ControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private ApplyCommand applyCommand; + + @MockBean + private ReportHolder reportHolder; + + @MockBean + private ProjectContextHolder contextHolder; + + @Test + void testGetRequest() throws Exception { + ProjectContext projectContext = mock(ProjectContext.class); + when(contextHolder.getProjectContext()).thenReturn(projectContext); + mockMvc.perform(get("/spring-boot-upgrade")).andExpect(status().isOk()); + mockMvc.perform(get("/spring-boot-upgrade")).andExpect(status().isOk()); + // For the first request the report is created by the runner, for following calls the report is created again + verify(applyCommand, times(1)).execute(projectContext, ReportController.REPORT_RECIPE); + } + + @Test + void testPostRequest() throws Exception { + ProjectContext projectContext = mock(ProjectContext.class); + when(contextHolder.getProjectContext()).thenReturn(projectContext); + mockMvc.perform(post("/spring-boot-upgrade") + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .param("recipeNames[]", "recipe1", "recipe2") + ).andExpect(status().isOk()); + verify(applyCommand).execute(projectContext, ReportController.REPORT_RECIPE); + } +} diff --git a/applications/rest-service/src/test/resources/test-code/bootify-jaxrs/pom.xml b/applications/spring-boot-upgrade/src/test/resources/test-code/bootify-jaxrs/pom.xml similarity index 100% rename from applications/rest-service/src/test/resources/test-code/bootify-jaxrs/pom.xml rename to applications/spring-boot-upgrade/src/test/resources/test-code/bootify-jaxrs/pom.xml diff --git a/applications/rest-service/src/test/resources/test-code/bootify-jaxrs/src/main/java/com/example/jee/app/PersonController.java b/applications/spring-boot-upgrade/src/test/resources/test-code/bootify-jaxrs/src/main/java/com/example/jee/app/PersonController.java similarity index 100% rename from applications/rest-service/src/test/resources/test-code/bootify-jaxrs/src/main/java/com/example/jee/app/PersonController.java rename to applications/spring-boot-upgrade/src/test/resources/test-code/bootify-jaxrs/src/main/java/com/example/jee/app/PersonController.java diff --git a/applications/spring-shell/src/test/java/org/springframework/sbm/MigrateSimpleMuleAppDataweaveIntegrationTest.java b/applications/spring-shell/src/test/java/org/springframework/sbm/MigrateSimpleMuleAppDataweaveIntegrationTest.java index f6106b988..e9ca0f6b2 100644 --- a/applications/spring-shell/src/test/java/org/springframework/sbm/MigrateSimpleMuleAppDataweaveIntegrationTest.java +++ b/applications/spring-shell/src/test/java/org/springframework/sbm/MigrateSimpleMuleAppDataweaveIntegrationTest.java @@ -64,6 +64,7 @@ public static void afterAll() { if (tmDataweaveContainer != null && tmDataweaveContainer.getContainer() != null) { tmDataweaveContainer.getContainer().stop(); } + System.setProperty("sbm.muleTriggerMeshTransformEnabled", "false"); } @Test diff --git a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeTestSupport.java b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeTestSupport.java index 3767cb7e8..7ae32ab48 100644 --- a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeTestSupport.java +++ b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeTestSupport.java @@ -21,6 +21,7 @@ import org.springframework.sbm.engine.recipe.*; import org.springframework.sbm.java.impl.RewriteJavaParser; import org.springframework.sbm.java.util.BasePackageCalculator; +import org.springframework.sbm.project.RewriteSourceFileWrapper; import org.springframework.sbm.project.resource.SbmApplicationProperties; import org.springframework.sbm.project.resource.ResourceHelper; import org.springframework.sbm.search.recipe.actions.OpenRewriteJavaSearchAction; @@ -34,10 +35,7 @@ import javax.validation.Validator; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -66,6 +64,9 @@ private RecipeTestSupport() { DefaultActionDeserializer.class, RewriteJavaSearchActionDeserializer.class, RewriteRecipeLoader.class, + RewriteRecipeRunner.class, + RewriteMigrationResultMerger.class, + RewriteSourceFileWrapper.class, SbmRecipeLoader.class, BasePackageCalculator.class, ProjectContextHolder.class @@ -86,10 +87,6 @@ public static void testRecipe(Path recipeFile, Consumer consumer, Class SpringBeanProvider.run(context -> { context.start(); - ActionDeserializerRegistry deserializerRegistry = context.getBean(ActionDeserializerRegistry.class); - ObjectMapper objectMapper = context.getBean("yamlObjectMapper", ObjectMapper.class); - - deserializerRegistry.register(OpenRewriteJavaSearchAction.class, new RewriteJavaSearchActionDeserializer(objectMapper, context.getBeanFactory())); RecipesBuilder recipesBuilder = context.getBean(RecipesBuilder.class); ResourceHelperDummy resourceHelperDummy = context.getBean(ResourceHelperDummy.class); resourceHelperDummy.setRecipe(recipeFile); diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java index 9edc5ac9c..0e028cc9f 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/git/GitSupport.java @@ -252,7 +252,7 @@ public void commitWhenGitAvailable(ProjectContext context, String appliedRecipeN .map(r -> context.getProjectRootDirectory().relativize(Path.of(r)).toString()) .collect(Collectors.toList()); - if (sbmApplicationProperties.isGitSupportEnabled() && !(modifiedResources.isEmpty() || deletedResources.isEmpty())) { + if (sbmApplicationProperties.isGitSupportEnabled() && (!modifiedResources.isEmpty() || !deletedResources.isEmpty())) { File repoDir = context.getProjectRootDirectory().toFile(); if (repoExists(repoDir)) { String commitMessage = "SBM: applied recipe '" + appliedRecipeName + "'"; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/ConditionDeserializer.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/ConditionDeserializer.java index fa4bbcbd5..fd4ab0fd5 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/ConditionDeserializer.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/ConditionDeserializer.java @@ -55,7 +55,7 @@ public Condition deserialize(JsonParser parser, DeserializationContext deseriali } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Unknown class [" + clazz + "]", e); } - if (!ClassUtils.getAllInterfacesForClassAsSet(conditionClass).contains(Condition.class)) { + if (!Condition.class.isAssignableFrom(conditionClass)) { throw new IllegalArgumentException("Class [" + clazz + "] doesn't implement Condition interface"); } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/SbmRecipeLoader.java b/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/SbmRecipeLoader.java index 0eee715f5..1b68467c4 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/SbmRecipeLoader.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/SbmRecipeLoader.java @@ -31,7 +31,7 @@ @RequiredArgsConstructor public class SbmRecipeLoader implements RecipeLoader { - static final String PATTERN = "classpath*:/recipes/*"; + static final String PATTERN = "classpath*:/recipes/**/*.yaml"; private final RecipeParser recipeParser; private final ResourceHelper resourceHelper; diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java index 0b9da5e3e..8171453dd 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java @@ -72,11 +72,15 @@ public Set mapCoordinatesToDependencies(List coordinates) { String[] parts = c.split(":"); - if (parts.length != 3) throw new IllegalArgumentException("Given coordinate is invalid '" + c + "'"); + if (parts.length < 2) throw new IllegalArgumentException("Given coordinate is invalid '" + c + "'"); String groupId = parts[0]; String artifactId = parts[1]; - String version = parts[2]; + String version = null; + if(parts.length == 3) { + version = parts[2]; + } + MavenRepository mavenRepository = new MavenRepository( "jcenter", diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/JavaSourceSetImplTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/JavaSourceSetImplTest.java index 0f7a36248..1c03f10a9 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/JavaSourceSetImplTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/impl/JavaSourceSetImplTest.java @@ -43,7 +43,6 @@ void testGetBasePackageShouldReturnDistinctRootPackageIfExists() { ""; JavaSourceSet sut = TestProjectContext.buildProjectContext() - .withDummyRootBuildFile() .withJavaSources(sourceCode1, sourceCode2) .build() .getApplicationModules().getRootModule().getMainJavaSourceSet(); diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java index 150ba1e87..553f69542 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java @@ -48,8 +48,9 @@ public static PomBuilder buiildPom(String parent, String artifactId) { return pomBuilder; } - public PomBuilder withModules(String... modules) { - this.modules = Arrays.asList(modules); + public PomBuilder withModules(String... moduleArtifactNames) { + this.modules = Arrays.asList(moduleArtifactNames); + if(this.modules.stream().anyMatch(m -> m.contains(":"))) throw new RuntimeException("Found ':' in artifact name but artifact names of modules must not be provided as coordinate."); return this; } diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java index 8be66bbfa..b613981d1 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java @@ -249,6 +249,9 @@ public static class Builder { private OpenRewriteMavenBuildFile mockedBuildFile; private DependencyHelper dependencyHelper = new DependencyHelper(); private SbmApplicationProperties sbmApplicationProperties = new SbmApplicationProperties(); + + private Optional springVersion = Optional.empty(); + private JavaParser javaParser; public Builder(Path projectRoot) { @@ -420,6 +423,9 @@ public Builder withMockedBuildFile(OpenRewriteMavenBuildFile mockedBuildFile) { return this; } + /** + * This method is obsolete to use as a default {@code pom.xml} is always added if not otherwise specified. + */ public Builder withDummyRootBuildFile() { if (containsAnyPomXml() || !dependencies.isEmpty()) throw new IllegalArgumentException("ProjectContext already contains pom.xml files."); @@ -456,14 +462,25 @@ public ProjectContext serializeProjectContext(Path targetDir) { public ProjectContext build() { verifyValidBuildFileSetup(); - if (dependencies != null && !dependencies.isEmpty()) { - String generatedPomXml = renderPomXmlWithGivenDependencies(); - resourcesWithRelativePaths.put(Path.of("pom.xml"), generatedPomXml); + if(!containsAnyPomXml()) { + String xml = "\n" + + "\n" + + " 4.0.0\n" + + "{{springParentPom}}" + + " com.example\n" + + " dummy-root\n" + + " 0.1.0-SNAPSHOT\n" + + " jar\n" + + "{{dependencies}}" + + "\n"; + + xml = xml + .replace("{{dependencies}}", getDependenciesSection()) + .replace("{{springParentPom}}", getSpringParentPomSection()); + + resourcesWithRelativePaths.put(Path.of("pom.xml"), xml); } - if (!containsAnyPomXml()) { - withDummyRootBuildFile(); - } // create resource map with fully qualified paths Map resourcesWithAbsolutePaths = new LinkedHashMap<>(); @@ -558,17 +575,22 @@ private ProjectContextInitializer createProjectContextInitializer(ProjectContext } private void verifyValidBuildFileSetup() { - boolean containsRootPom = resourcesWithRelativePaths.containsKey(Path.of("pom.xml")); boolean isClasspathGiven = dependencies != null && !dependencies.isEmpty(); boolean isMockedBuildFileGiven = mockedBuildFile != null; - - if (containsRootPom && isClasspathGiven) { - throw new IllegalArgumentException("Found classpath entries and a root pom.xml in resources. When classpath is provided the root pom gets generated"); - } else if (containsRootPom && isMockedBuildFileGiven) { - throw new IllegalArgumentException("Found mocked BuildFile and a root pom.xml in resources. When mocked BuildFile is provided no other pom.xml must exist"); + boolean hasSpringBootParent = this.springVersion.isPresent(); + boolean containsAnyPomXml = containsAnyPomXml(); + + if (containsAnyPomXml && isClasspathGiven) { + throw new IllegalArgumentException("Found classpath entries and pom.xml in resources. When classpath is provided the root pom gets generated"); + } else if (containsAnyPomXml && hasSpringBootParent) { + throw new IllegalArgumentException("Found spring boot version for parent pom and root pom.xml in resources. When spring boot version is provided the root pom gets generated"); + } else if (containsAnyPomXml && isMockedBuildFileGiven) { + throw new IllegalArgumentException("Found mocked BuildFile and root pom.xml in resources. When mocked BuildFile is provided no other pom.xml must exist"); } if (mockedBuildFile != null && isClasspathGiven) { throw new IllegalArgumentException("Found mocked BuildFile and classpath entries. When mocked BuildFile is provided no other pom.xml must exist"); + } else if(mockedBuildFile != null && hasSpringBootParent) { + throw new IllegalArgumentException("Found mocked BuildFile and Spring Boot version. When mocked BuildFile is provided no other pom.xml, parent or dependencies must exist"); } } @@ -588,36 +610,53 @@ private Parser.Input createParserInput(Path path, String value) { @NotNull - private String renderPomXmlWithGivenDependencies() { - String xml = "\n" + - "\n" + - " 4.0.0\n" + - " com.example\n" + - " dummy-root\n" + - " 0.1.0-SNAPSHOT\n" + - " jar\n" + - "{{dependencies}}\n" + - "\n"; - - String dependenciesText = null; - if(dependencies.isEmpty()) { - dependenciesText = ""; - } else { - StringBuilder dependenciesSection = new StringBuilder(); + private String getDependenciesSection() { + StringBuilder dependenciesSection = new StringBuilder(); + if(!dependencies.isEmpty()) { dependenciesSection.append(" ").append("").append("\n"); dependencyHelper.mapCoordinatesToDependencies(dependencies).stream().forEach(dependency -> { dependenciesSection.append(" ").append(" ").append("").append("\n"); dependenciesSection.append(" ").append(" ").append(" ").append("").append(dependency.getGroupId()).append("").append("\n"); dependenciesSection.append(" ").append(" ").append(" ").append("").append(dependency.getArtifactId()).append("").append("\n"); - dependenciesSection.append(" ").append(" ").append(" ").append("").append(dependency.getVersion()).append("").append("\n"); + if(dependency.getVersion() != null) { + dependenciesSection + .append(" ") + .append(" ") + .append(" ") + .append("") + .append(dependency.getVersion()) + .append("") + .append("\n"); + } dependenciesSection.append(" ").append(" ").append("").append("\n"); }); dependenciesSection.append(" ").append("").append("\n"); - dependenciesText = dependenciesSection.toString(); } - String buildFileSource = xml.replace("{{dependencies}}", dependenciesText); - return buildFileSource; + return dependenciesSection.toString(); + } + + @NotNull + private String getSpringParentPomSection() { + + if (this.springVersion.isPresent()) { + return """ + + org.springframework.boot + spring-boot-starter-parent + %s + + + """.formatted(this.springVersion.get()); + } + + return ""; + } + + public Builder withSpringBootParentOf(String springVersion) { + + this.springVersion = Optional.of(springVersion); + return this; } } diff --git a/components/sbm-recipes-boot-upgrade/demo.html b/components/sbm-recipes-boot-upgrade/demo.html new file mode 100644 index 000000000..2afa7b657 --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/demo.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java index 68accef7a..04521c9e2 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java @@ -36,6 +36,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; /** * Special Action generates a Spring Boot Upgrade report. @@ -136,6 +139,8 @@ private String renderReport(String renderedHeader, List sections, String String content = """ ${header} + ${allRecipesButton} + <#list sections as changeSection> ${changeSection} @@ -144,6 +149,7 @@ private String renderReport(String renderedHeader, List sections, String """; Map data = Map.of( + "allRecipesButton", renderRunAllRecipesButton(), "header", renderedHeader, "sections", sections, "footer", renderedFooter @@ -153,6 +159,42 @@ private String renderReport(String renderedHeader, List sections, String return renderedTemplate; } + private String renderRunAllRecipesButton() { + + StringBuilder sb = new StringBuilder(); + + List recipes = sections + .stream() + .flatMap(section -> section.getRemediation().getPossibilities().stream()) + .map(p -> p.getRecipe()) + .filter(recipe -> recipe != null && !recipe.isEmpty()) + .collect(Collectors.toList()); + + String renderedRecipeInputs = IntStream + .range(0, recipes.size()) + .mapToObj(idx -> "") + .collect(Collectors.joining("\n")); + +/* +
+ + + +*/ + + + String buttonCode = """ + ++++ +
+ +
+ ++++ + """; + return buttonCode.replace("", renderedRecipeInputs); + + } + private String renderTemplate(String key, String content, Map data) { try (StringWriter writer = new StringWriter()) { diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java index 8f062ffd3..e7457ad9e 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportSection.java @@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.recipe.Condition; +import org.stringtemplate.v4.ST; import javax.validation.constraints.NotEmpty; import java.io.IOException; @@ -123,7 +124,7 @@ public String render(ProjectContext context) { throw new RuntimeException(e); } } - throw new IllegalArgumentException("Could not render Sectipn '"+ getTitle()+"', evaluating the context returned false"); + throw new IllegalArgumentException("Could not render Section '"+ getTitle()+"', evaluating the context returned false"); } private void renderTemplate(Map params, StringWriter writer, String templateContent) throws IOException, TemplateException { @@ -208,11 +209,8 @@ private void renderGitHubInfo(StringBuilder sb) { if(contributors != null) { List authors = getAuthors(); sb.append("Contributors: "); - authors.stream() - .forEach(a -> { - sb.append("https://github.com/").append(a.getHandle()).append("[@").append(a.getHandle()).append("^, role=\"ext-link\"]"); - }); - sb.append(ls); + String authorsString = authors.stream().map(a -> "https://github.com/" + a.getHandle() + "[@" + a.getHandle() + "^, role=\"ext-link\"]").collect(Collectors.joining(", ")); + sb.append(authorsString).append(ls); } } @@ -240,6 +238,7 @@ private String renderRemediation() { sb.append(remediation.getDescription()).append(ls).append(ls); if(remediation.getPossibilities().isEmpty()) { renderResourcesList(sb, remediation); + renderRecipeButton(sb, remediation.getRecipe()); } else { remediation.getPossibilities().forEach(p -> renderRemediationPossibility(sb, p)); } @@ -250,17 +249,35 @@ private void renderRemediationPossibility(StringBuilder sb, RemediationPossibili sb.append("===== ").append(p.getTitle()).append(ls); sb.append(p.getDescription()).append(ls).append(ls); renderResourcesList(sb, p); - if(p.getRecipe() != null) { - sb.append(p.getRecipe()).append(ls).append(ls); -// ST st = new ST( -// """ -// ++++ -// -// ++++ -// """ -// ); -// st.add("RECIPE_NAME", p.getRecipe()); -// sb.append(st.render()); + renderRecipeButton(sb, p.getRecipe()); + } + + private void renderRecipeButton(StringBuilder sb, String recipe) { + if(recipe != null && !recipe.isEmpty()) { + sb.append(ls).append(ls); + /* + + + + */ + String buttonCode = """ + ++++ +
+
+ ++++ + """; + buttonCode = buttonCode.replace("", recipe); + sb.append(buttonCode); } } diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/AddSpringBootRepositoriesHelper.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/AddSpringBootRepositoriesHelper.java new file mode 100644 index 000000000..202ae7aab --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/AddSpringBootRepositoriesHelper.java @@ -0,0 +1,41 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.sbm.boot.upgrade_27_30.report.helper; + +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportSection; +import org.springframework.sbm.build.migration.conditions.NoPluginRepositoryExistsCondition; +import org.springframework.sbm.build.migration.conditions.NoRepositoryExistsCondition; +import org.springframework.sbm.engine.context.ProjectContext; + +import java.util.Map; + +public class AddSpringBootRepositoriesHelper implements SpringBootUpgradeReportSection.Helper{ + @Override + public String getDescription() { + return null; + } + + @Override + public boolean evaluate(ProjectContext context) { + return new NoRepositoryExistsCondition().evaluate(context) && new NoPluginRepositoryExistsCondition().evaluate(context); + } + + @Override + public Map getData() { + return Map.of(); + } +} diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelper.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelper.java index fd7d63f3e..53ea8e1bc 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelper.java +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelper.java @@ -20,6 +20,7 @@ import org.openrewrite.ExecutionContext; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.J; +import org.springframework.sbm.boot.common.conditions.IsSpringBootProject; import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportSection; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.project.resource.RewriteSourceFileHolder; @@ -42,6 +43,13 @@ public String getDescription() { @Override public boolean evaluate(ProjectContext context) { + IsSpringBootProject isSpringBootProject = new IsSpringBootProject(); + isSpringBootProject.setVersionPattern("2\\.7\\..*|3\\.0\\..*"); + boolean isSpringBootApplication = isSpringBootProject.evaluate(context); + if(!isSpringBootApplication) { + return false; + } + //CrudRepositoryExtension List> pagingAndSortingFileHolders = context.getProjectJavaSources().find(pagingAndSortingFinders("org.springframework.data.repository.PagingAndSortingRepository")); diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeDependenciesHelper.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeDependenciesHelper.java new file mode 100644 index 000000000..8c367210b --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeDependenciesHelper.java @@ -0,0 +1,46 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm.boot.upgrade_27_30.report.helper; + +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportAction; +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportSection; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.java.api.JavaSource; + +import java.util.List; +import java.util.Map; + +/** + * @author Fabian Krüger + */ +public class UpgradeDependenciesHelper implements SpringBootUpgradeReportSection.Helper> { + @Override + public String getDescription() { + return ""; + } + + @Override + public boolean evaluate(ProjectContext context) { + // FIXME: dummy + return true; + } + + @Override + public Map> getData() { + // FIXME: dummy + return Map.of("ehcache", List.of("org.ehcache:ehcache:3.10.0")); + } +} diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeSpringBootVersionHelper.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeSpringBootVersionHelper.java new file mode 100644 index 000000000..8cb1a717c --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeSpringBootVersionHelper.java @@ -0,0 +1,47 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm.boot.upgrade_27_30.report.helper; + +import org.springframework.sbm.boot.common.conditions.IsSpringBootProject; +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportSection; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.java.api.JavaSource; + +import java.util.List; +import java.util.Map; + +/** + * @author Fabian Krüger + */ +public class UpgradeSpringBootVersionHelper implements SpringBootUpgradeReportSection.Helper { + @Override + public String getDescription() { + return ""; + } + + @Override + public boolean evaluate(ProjectContext context) { + IsSpringBootProject isSpringBootProject = new IsSpringBootProject(); + isSpringBootProject.setVersionPattern("2\\.7\\..*"); + return isSpringBootProject.evaluate(context); + } + + @Override + public Map getData() { + // FIXME: Provide correct boot version, see https://github.com/spring-projects-experimental/spring-boot-migrator/issues/560 + return Map.of("bootVersion", "2.7.3"); + } +} diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/sbu30-225-logging-date-format.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-225-logging-date-format.yaml similarity index 100% rename from components/sbm-recipes-boot-upgrade/src/main/resources/recipes/sbu30-225-logging-date-format.yaml rename to components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-225-logging-date-format.yaml diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-add-milestone-repositories.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-add-milestone-repositories.yaml new file mode 100644 index 000000000..f262e928d --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-add-milestone-repositories.yaml @@ -0,0 +1,25 @@ +- name: sbu30-add-milestone-repositories + description: Spring boot 3.0 Upgrade - Add milestone repository for dependencies and plugins + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + + actions: + - type: org.springframework.sbm.build.migration.actions.AddRepositoryAction + description: Add Spring Boot milestone repository. + id: "spring-milestone" + url: "https://repo.spring.io/milestone" + snapshotsEnabled: false + condition: + type: org.springframework.sbm.build.migration.conditions.NoRepositoryExistsCondition + id: "spring-milestone" + url: "https://repo.spring.io/milestone" + + - type: org.springframework.sbm.build.migration.actions.AddPluginRepositoryAction + description: Add Spring Boot milestone plugin repository. + id: "spring-milestone" + url: "https://repo.spring.io/milestone" + snapshotsEnabled: false + condition: + type: org.springframework.sbm.build.migration.conditions.NoPluginRepositoryExistsCondition + id: "spring-milestone" + url: "https://repo.spring.io/milestone" diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-migrate-spring-data-properties.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-migrate-spring-data-properties.yaml new file mode 100644 index 000000000..717987466 --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-migrate-spring-data-properties.yaml @@ -0,0 +1,477 @@ +- name: sbu30-migrate-spring-data-properties + description: Spring boot 3.0 Upgrade - Migrate 'spring.data' properties to new property names + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + + - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter + condition: + type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject + versionPattern: "3\\.0\\..*" + description: Migrate configuration to SpringBoot 3.0 in properties format + openRewriteRecipe: |- + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.java.spring.boot2.SpringBootPropertiesManual_2_7 + displayName: Migrate configuration to Spring Boot 3.0 in properties format + description: All relevant configurations in property format will be migrated to SpringBoot 3.0 properties + recipeList: + # update properties + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.connection-timeout + newPropertyKey: spring.elasticsearch.connection-timeout + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.connection-timeout + newPropertyKey: spring.elasticsearch.connection-timeout + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.max-in-memory-size + newPropertyKey: spring.elasticsearch.webclient.max-in-memory-size + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.max-in-memory-size + newPropertyKey: spring.elasticsearch.webclient.max-in-memory-size + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.password + newPropertyKey: spring.elasticsearch.password + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.password + newPropertyKey: spring.elasticsearch.password + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.socket-timeout + newPropertyKey: spring.elasticsearch.socket-timeout + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.socket-timeout + newPropertyKey: spring.elasticsearch.socket-timeout + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.username + newPropertyKey: spring.elasticsearch.username + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.data.elasticsearch.client.reactive.username + newPropertyKey: spring.elasticsearch.username + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.continue-on-error + newPropertyKey: spring.sql.init.continue-on-error + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.continue-on-error + newPropertyKey: spring.sql.init.continue-on-error + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.data + newPropertyKey: spring.sql.init.data-locations + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.data + newPropertyKey: spring.sql.init.data-locations + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.data-password + newPropertyKey: spring.sql.init.password + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.data-password + newPropertyKey: spring.sql.init.password + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.data-username + newPropertyKey: spring.sql.init.username + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.data-username + newPropertyKey: spring.sql.init.username + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.initialization-mode + newPropertyKey: spring.sql.init.mode + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.initialization-mode + newPropertyKey: spring.sql.init.mode + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.platform + newPropertyKey: spring.sql.init.platform + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.platform + newPropertyKey: spring.sql.init.platform + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.schema + newPropertyKey: spring.sql.init.schema-locations + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.schema + newPropertyKey: spring.sql.init.schema-locations + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.schema-password + newPropertyKey: spring.sql.init.password + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.schema-password + newPropertyKey: spring.sql.init.password + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.schema-username + newPropertyKey: spring.sql.init.username + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.schema-username + newPropertyKey: spring.sql.init.username + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.separator + newPropertyKey: spring.sql.init.separator + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.separator + newPropertyKey: spring.sql.init.separator + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.datasource.sql-script-encoding + newPropertyKey: spring.sql.init.encoding + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.datasource.sql-script-encoding + newPropertyKey: spring.sql.init.encoding + + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.connection-timeout + newPropertyKey: spring.elasticsearch.connection-timeout + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.connection-timeout + newPropertyKey: spring.elasticsearch.connection-timeout + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.password + newPropertyKey: spring.elasticsearch.password + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.password + newPropertyKey: spring.elasticsearch.password + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.read-timeout + newPropertyKey: spring.elasticsearch.socket-timeout + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.read-timeout + newPropertyKey: spring.elasticsearch.socket-timeout + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.sniffer.delay-after-failure + newPropertyKey: spring.elasticsearch.restclient.sniffer.delay-after-failure + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.sniffer.delay-after-failure + newPropertyKey: spring.elasticsearch.restclient.sniffer.delay-after-failure + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.sniffer.interval + newPropertyKey: spring.elasticsearch.restclient.sniffer.interval + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.sniffer.interval + newPropertyKey: spring.elasticsearch.restclient.sniffer.interval + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.username + newPropertyKey: spring.elasticsearch.username + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.elasticsearch.rest.username + newPropertyKey: spring.elasticsearch.username + - org.openrewrite.yaml.ChangePropertyKey: + oldPropertyKey: spring.webflux.session.cookie.same-site + newPropertyKey: server.reactive.session.cookie.same-site + - org.openrewrite.properties.ChangePropertyKey: + oldPropertyKey: spring.webflux.session.cookie.same-site + newPropertyKey: server.reactive.session.cookie.same-site + # remove properties + - org.openrewrite.yaml.DeleteProperty: + propertyKey: management.endpoint.jolokia.config + - org.openrewrite.properties.DeleteProperty: + propertyKey: management.endpoint.jolokia.config + - org.openrewrite.yaml.DeleteProperty: + propertyKey: management.endpoint.jolokia.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: management.endpoint.jolokia.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: management.metrics.graphql.autotime.percentiles + - org.openrewrite.properties.DeleteProperty: + propertyKey: management.metrics.graphql.autotime.percentiles + - org.openrewrite.yaml.DeleteProperty: + propertyKey: management.metrics.graphql.autotime.percentiles-histogram + - org.openrewrite.properties.DeleteProperty: + propertyKey: management.metrics.graphql.autotime.percentiles-histogram + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.broker-url + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.broker-url + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.close-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.close-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.in-memory + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.in-memory + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.non-blocking-redelivery + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.non-blocking-redelivery + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.packages.trust-all + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.packages.trust-all + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.packages.trusted + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.packages.trusted + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.password + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.password + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.block-if-full + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.block-if-full + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.block-if-full-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.block-if-full-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.idle-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.idle-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.max-connections + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.max-connections + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.max-sessions-per-connection + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.max-sessions-per-connection + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.time-between-expiration-check + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.time-between-expiration-check + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.pool.use-anonymous-producers + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.pool.use-anonymous-producers + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.send-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.send-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.activemq.user + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.activemq.user + + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.block-if-full + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.block-if-full + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.block-if-full-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.block-if-full-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.idle-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.idle-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.max-connections + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.max-connections + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.max-sessions-per-connection + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.max-sessions-per-connection + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.time-between-expiration-check + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.time-between-expiration-check + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.artemis.pool.use-anonymous-producers + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.artemis.pool.use-anonymous-producers + + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.cache.ehcache.config + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.cache.ehcache.config + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.cache.infinispan.config + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.cache.infinispan.config + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.config.use-legacy-processing + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.config.use-legacy-processing + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.data.elasticsearch.client.reactive.use-ssl + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.data.elasticsearch.client.reactive.use-ssl + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.h2.console.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.h2.console.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.h2.console.path + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.h2.console.path + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.h2.console.settings.trace + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.h2.console.settings.trace + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.h2.console.settings.web-admin-password + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.h2.console.settings.web-admin-password + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.h2.console.settings.web-allow-others + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.h2.console.settings.web-allow-others + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jersey.application-path + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jersey.application-path + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jersey.filter.order + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jersey.filter.order + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jersey.init + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jersey.init + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jersey.servlet.load-on-startup + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jersey.servlet.load-on-startup + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jersey.type + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jersey.type + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.allow-credentials + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.allow-credentials + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-headers + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-headers + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-methods + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-methods + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-origin-patterns + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-origin-patterns + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-origins + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.allowed-origins + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.exposed-headers + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.exposed-headers + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.cors.max-age + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.cors.max-age + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.graphiql.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.graphiql.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.graphiql.path + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.graphiql.path + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.path + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.path + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.schema.file-extensions + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.schema.file-extensions + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.schema.introspection.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.schema.introspection.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.schema.locations + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.schema.locations + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.schema.printer.enabled + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.schema.printer.enabled + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.websocket.connection-init-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.websocket.connection-init-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.graphql.websocket.path + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.graphql.websocket.path + + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.allow-sub-transactions + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.allow-sub-transactions + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.checkpoint-interval + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.checkpoint-interval + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.default-jta-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.default-jta-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.default-max-wait-time-on-shutdown + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.default-max-wait-time-on-shutdown + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.enable-logging + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.enable-logging + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.force-shutdown-on-vm-exit + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.force-shutdown-on-vm-exit + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.log-base-dir + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.log-base-dir + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.log-base-name + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.log-base-name + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.max-actives + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.max-actives + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.max-timeout + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.max-timeout + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.delay + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.delay + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.forget-orphaned-log-entries-delay + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.forget-orphaned-log-entries-delay + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.max-retries + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.max-retries + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.retry-interval + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.recovery.retry-interval + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.serial-jta-transactions + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.serial-jta-transactions + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.service + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.service + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.threaded-two-phase-commit + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.threaded-two-phase-commit + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.transaction-manager-unique-name + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.atomikos.properties.transaction-manager-unique-name + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.transaction-manager-id + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.transaction-manager-id + - org.openrewrite.yaml.DeleteProperty: + propertyKey: spring.jta.log-dir + - org.openrewrite.properties.DeleteProperty: + propertyKey: spring.jta.log-dir \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-migrate-to-jakarta-packages.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-migrate-to-jakarta-packages.yaml new file mode 100644 index 000000000..91036f69a --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-migrate-to-jakarta-packages.yaml @@ -0,0 +1,12 @@ +- name: sbu30-migrate-javax-to-jakarta + description: Spring boot 3.0 Upgrade - Migrate javax packages to new jakarta packages + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + + - type: org.springframework.sbm.engine.recipe.OpenRewriteNamedRecipeAdapter + condition: + type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject + versionPattern: "3\\.0\\..*" + description: Replace javax with new jakarta packages + openRewriteRecipeName: org.openrewrite.java.migrate.JavaxMigrationToJakarta \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-paging-and-sorting-repository.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-paging-and-sorting-repository.yaml new file mode 100644 index 000000000..7341a9324 --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-paging-and-sorting-repository.yaml @@ -0,0 +1,25 @@ +- name: sbu30-paging-and-sorting-repository + description: Spring boot 3.0 Upgrade - Add CrudRepository interface extension additionally to PagingAndSortingRepository + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + + - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter + condition: + type: org.springframework.sbm.boot.upgrade_27_30.report.helper.PagingAndSortingHelper + description: Add CrudRepository interface extension additionally to PagingAndSortingRepository + openRewriteRecipe: |- + type: specs.openrewrite.org/v1beta/recipe + name: org.springframework.sbm.boot.upgrade_27_30.SpringBootPropertiesManual_2_7CrudRepo + displayName: Add CrudRepository interface extension additionaly to PagingAndSortingRepository + description: Add CrudRepository interface extension additionaly to PagingAndSortingRepository + recipeList: + - org.springframework.sbm.boot.upgrade_27_30.CrudRepositoryExtension: + pagingAndSortingRepository: org.springframework.data.repository.PagingAndSortingRepository + targetCrudRepository: org.springframework.data.repository.CrudRepository + - org.springframework.sbm.boot.upgrade_27_30.CrudRepositoryExtension: + pagingAndSortingRepository: org.springframework.data.repository.reactive.ReactiveSortingRepository + targetCrudRepository: org.springframework.data.repository.reactive.ReactiveCrudRepository + - org.springframework.sbm.boot.upgrade_27_30.CrudRepositoryExtension: + pagingAndSortingRepository: org.springframework.data.repository.reactive.RxJava3SortingRepository + targetCrudRepository: org.springframework.data.repository.reactive.RxJava3CrudRepository diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/sbu30-remove-construtor-binding.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-remove-construtor-binding.yaml similarity index 87% rename from components/sbm-recipes-boot-upgrade/src/main/resources/recipes/sbu30-remove-construtor-binding.yaml rename to components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-remove-construtor-binding.yaml index 3b1bd2105..40f261c6d 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/sbu30-remove-construtor-binding.yaml +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-remove-construtor-binding.yaml @@ -7,12 +7,12 @@ - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject - versionPattern: "3\\.0\\..*" + versionPattern: "2\\.7\\..*|3\\.0\\..*" description: Remove redundant @ConstructorBinding annotations when applicable openRewriteRecipe: |- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.spring.boot3.ImprovedConstructorBinding - displayName: Migrate additional Spring Boot properties to 2.7 + displayName: Remove redundant @ConstructorBinding annotations description: Remove redundant @ConstructorBinding annotations when applicable recipeList: - org.openrewrite.java.spring.boot3.RemoveConstructorBindingAnnotation diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-remove-image-banner.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-remove-image-banner.yaml new file mode 100644 index 000000000..9806767ba --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-remove-image-banner.yaml @@ -0,0 +1,17 @@ +- name: sbu30-remove-image-banner + description: Spring boot 3.0 Upgrade - Remove the image banner at src/main/resources + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter + condition: + type: org.springframework.sbm.boot.upgrade_27_30.report.helper.BannerSupportHelper + description: Remove the image banner at src/main/resources + openRewriteRecipe: |- + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.RemoveSpringBootImageBanner + displayName: Remove the image banner at `src/main/resources` + description: Remove the image banner at `src/main/resources` + recipeList: + - org.openrewrite.DeleteSourceFiles: + filePattern: "{**/src,src}/main/resources/banner.{gif,png,jpg}" \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-set-java-version.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-set-java-version.yaml new file mode 100644 index 000000000..0d491e0d4 --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-set-java-version.yaml @@ -0,0 +1,12 @@ +- name: sbu30-set-java-version + description: Spring boot 3.0 Upgrade - Set java version property in build file + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + + - type: org.springframework.sbm.build.migration.actions.SetProperty + propertyName: "java.version" + propertyValue: "17" + description: Set Java version to 17 + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-upgrade-boot-version.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-upgrade-boot-version.yaml new file mode 100644 index 000000000..fbf8f7c10 --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-upgrade-boot-version.yaml @@ -0,0 +1,28 @@ +- name: sbu30-upgrade-boot-version + description: Spring boot 3.0 Upgrade - Upgrade Spring Boot version + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + + - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter + condition: + type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject + versionPattern: "2\\.7\\..*" + description: Bump Spring Boot to 3.0.0-RC2 + openRewriteRecipe: |- + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.java.spring.boot3.data.UpgradeSpringData30 + displayName: Upgrade to SpringBoot 3.0 + description: 'Upgrade to SpringBoot to 3.0 from any prior version.' + recipeList: + - org.openrewrite.maven.spring.UpgradeUnmanagedSpringProject: + versionPattern: "2\\.7\\..*" + newVersion: 3.0.0-RC2 + - org.openrewrite.maven.UpgradeParentVersion: + groupId: org.springframework.boot + artifactId: spring-boot-starter-parent + newVersion: 3.0.0-RC2 + - org.openrewrite.maven.UpgradeDependencyVersion: + groupId: org.springframework.boot + artifactId: spring-boot-dependencies + newVersion: 3.0.0-RC2 \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-upgrade-dependencies.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-upgrade-dependencies.yaml new file mode 100644 index 000000000..563e9a19f --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/migration/sbu30-upgrade-dependencies.yaml @@ -0,0 +1,38 @@ +- name: sbu30-upgrade-dependencies + description: Spring boot 3.0 Upgrade - Upgrade dependencies + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition + actions: + + - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter + condition: + type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject + versionPattern: "2\\.7\\..*|3\\.0\\..*" + description: Upgrade dependencies for Spring Boot 3.0 + openRewriteRecipe: |- + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.java.spring.boot3.data.UpgradeSSpringBoot3Dependencies + displayName: Upgrade to SpringBoot 3.0 + description: 'Upgrade to SpringBoot to 3.0 from any prior version.' + recipeList: + - org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId: + oldGroupId: org.ehcache + oldArtifactId: ehcache + overrideManagedVersion: true + newVersion: 3.10.2 + - org.openrewrite.maven.ChangeDependencyClassifier: + groupId: org.ehcache + artifactId: ehcache + newClassifier: jakarta + - org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId: + oldGroupId: com.github.tomakehurst + oldArtifactId: wiremock-jre8 + newGroupId: com.github.tomakehurst + newArtifactId: wiremock-jre8-standalone + newVersion: 2.34.0 + - org.openrewrite.maven.ChangeDependencyGroupIdAndArtifactId: + oldGroupId: com.github.tomakehurst + oldArtifactId: wiremock-jre8 + newGroupId: com.github.tomakehurst + newArtifactId: wiremock-jre8-standalone + newVersion: 2.34.0 \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-new-report.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/report/sbu30-report.yaml similarity index 82% rename from components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-new-report.yaml rename to components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/report/sbu30-report.yaml index c7e859817..aeb40cd6e 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-new-report.yaml +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/report/sbu30-report.yaml @@ -1,4 +1,4 @@ -- name: boot-2.7-3.0-upgrade-report2 +- name: sbu30-report description: Create a report for Spring Boot Upgrade from 2.7.x to 3.0.x condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -23,12 +23,11 @@ :source-highlighter: highlight.js :highlightjs-languages: java - :linkcss: :doctype: book :idprefix: :idseparator: - :toc: left - :sectnumlevels: 2 + :sectnumlevels: 3 :toclevels: 3 :tabsize: 4 :numbered: @@ -41,7 +40,8 @@ :spring-boot-artifactory-repo: snapshot :github-tag: main :spring-boot-version: current - + :stylesheet: /css/button.css + == Introduction This report aims to help with updating spring Boot applications from 2.7 to 3.0. The listed changes should be applied in the given order. @@ -60,13 +60,13 @@ <#assign coordinates>${scannedCoordinate} [cols="1h,3"] |=== - | Scanned dir | `${scannedProjectRoot}` + | Scanned dir | ${scannedProjectRoot} | Revision | <#if revision?has_content>`${revision}`<#else>Scanned project not under Git <#if projectName?has_content> | Project name | ${projectName} - | Coordinate | `${scannedCoordinate}` - | Boot version | `${bootVersion}` + | Coordinate | ${scannedCoordinate} + | Boot version | ${bootVersion} <#if numberOfChanges?has_content> | Changes | ${numberOfChanges} @@ -86,6 +86,52 @@ sections: + + - title: Add Spring Boot dependency and plugin milestone repository + helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.AddSpringBootRepositoriesHelper + change: |- + As currently only milestone releases exist these are required + affected: |- + You want to update to 3.0 so you're affected + remediation: + description: |- + Add Spring Boot milestone repositories. + recipe: sbu30-add-milestone-repositories + gitHubIssue: 441 + contributors: + - "Fabian Krüger[@fabapp2]" + + - title: Upgrade Dependencies + helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.UpgradeDependenciesHelper + change: |- + Spring Boot 3.0 upgraded many used dependencies. + Also, dependencies previously in the `javax` packages use the new `jakarta` packages now. + WARNING: THis is a dummy and needs to be replaced with the matching changes from the release notes! + affected: |- + List the found dependencies here? + remediation: + description: |- + A comprehensive list of affected dependencies and their new replacements + recipe: sbu30-upgrade-dependencies + contributors: + - "Fabian Krüger[@fabapp2]" + + - title: Upgrade Spring Boot Version to 3.0 + helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.UpgradeSpringBootVersionHelper + change: |- + The Spring Boot version changed to 3.0 + affected: |- + Upgrading to Spring Boot 3.0 requires an upgrade of the current Spring Boot version. + remediation: + description: |- + Depending on the way Spring Boot is added, e.g. by referencing `spring-boot-starter-parent` or through + `dependencyManagement` these need to be changed to upgrade to Spring Boot 3.0. + recipe: sbu30-upgrade-boot-version + githubIssue: TODO + contributors: + - "Fabian Krüger[@fabapp2]" + + - title: Changes to Data Properties helper: org.springframework.sbm.boot.upgrade_27_30.report.helper.ChangesToDataPropertiesHelper change: |- @@ -103,6 +149,7 @@ remediation: description: |- Either add `spring-data` dependency, rename the property or remove it in case it's not required anymore. + recipe: sbu30-migrate-spring-data-properties gitHubIssue: 441 contributors: - "Fabian Krüger[@fabapp2]" @@ -122,8 +169,8 @@ remediation: description: |- Set `logging.pattern.dateformat=yyyy-MM-dd HH:mm:ss.SSS` to fall back to the previous log format. + recipe: sbu30-225-logging-date-format gitHubIssue: 489 - recipe: sbu30-225-logging-date-format contributors: - "Fabian Krüger[@fabapp2]" @@ -136,14 +183,33 @@ The scan found banner image files here: <#list files as file> - * ${file} + * `${file}` remediation: - description: |- - remove image banners and replace it with text-banner with banner.txt file + description: "" + possibilities: + - title: Remove image banner + description: |- + Remove these image banners + + <#list files as file> + * `${file}` + + recipe: sbu30-remove-image-banner + - title: Replace image banner + description: |- + Replace these banners + + <#list files as file> + * `${file}` + + + with `banner.txt` + gitHubIssue: 150 contributors: - "Sandeep Nagaraj[@sanagaraj-pivotal]" + - "Fabian Krüger[@fabapp2]" - title: Constructor Binding @@ -174,6 +240,7 @@ for more information resources: - https://github.com/spring-projects-experimental/spring-boot-migrator/issues/166[Issue 166] + recipe: sbu30-remove-construtor-binding gitHubIssue: 166 recipe: boot-2.7-3.0-upgrade-report contributors: @@ -319,6 +386,7 @@ remediation: description: |- If one requires the old behavior one must extend not only the sorting repository, but also the respective CRUD repository explicitly. This was done so the sorting support could easily be combined with the List repositories introduced above. + recipe: sbu30-paging-and-sorting-repository gitHubIssue: 518 contributors: - "Sandeep Nagaraj[@sanagaraj-pivotal]" diff --git a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-2.7-3.0-dependency-version-update.yaml b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-2.7-3.0-dependency-version-update.yaml index 1e16b709c..063846ce1 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-2.7-3.0-dependency-version-update.yaml +++ b/components/sbm-recipes-boot-upgrade/src/main/resources/recipes/boot-2.7-3.0-dependency-version-update.yaml @@ -5,10 +5,10 @@ versionPattern: "2\\.7\\..*|3\\.0\\..*" actions: -# - type: org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionChecks -# description: "Check if the application adheres to preconditions." -# condition: -# type: org.springframework.sbm.common.migration.conditions.TrueCondition + - type: org.springframework.sbm.boot.upgrade_27_30.Sbu30_PreconditionChecks + description: "Check if the application adheres to preconditions." + condition: + type: org.springframework.sbm.common.migration.conditions.TrueCondition # TODO: upgrades for 2.7 - type: org.springframework.sbm.build.migration.actions.AddRepositoryAction @@ -46,7 +46,6 @@ groupId: org.springframework.cloud artifactId: spring-cloud-dependencies newVersion: 2022.0.0-M4 - - type: org.springframework.sbm.boot.upgrade.common.actions.CreateAutoconfigurationAction description: Move EnableAutoConfiguration Property from spring.factories to AutoConfiguration.imports snapshotsEnabled: false @@ -87,7 +86,6 @@ groupId: org.springframework.boot artifactId: spring-boot-dependencies newVersion: 3.0.0-M3 - - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -111,7 +109,7 @@ newGroupId: com.github.tomakehurst newArtifactId: wiremock-jre8-standalone newVersion: 2.34.0 - + # Also moved to sbu30- - type: org.springframework.sbm.build.migration.actions.SetProperty propertyName: "java.version" propertyValue: "17" @@ -133,7 +131,6 @@ - org.openrewrite.yaml.ChangeKey: oldKeyPath: $.spring.security.saml2.relyingparty.registration.*[?(@.identityprovider)] newKey: assertingparty - - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -146,7 +143,6 @@ description: Renames spring.security.saml2.relyingparty.registration.(any).identityprovider to spring.security.saml2.relyingparty.registration.(any).assertingparty. recipeList: - org.springframework.sbm.boot.upgrade_27_30.SamlRelyingPartyPropertyApplicationPropertiesMove - - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -161,7 +157,6 @@ - org.openrewrite.yaml.ChangePropertyKey: oldPropertyKey: spring.data.cassandra newPropertyKey: spring.cassandra - - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -174,11 +169,10 @@ description: Renames spring.data.cassandra.(any) to spring.cassandra.(any) recipeList: - org.springframework.sbm.boot.upgrade_27_30.CassandraApplicationPropertiesMove - - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject - versionPattern: "3\\.0\\..*" + versionPattern: "2\\.7\\..*|3\\.0\\..*" description: Remove redundant @ConstructorBinding annotations when applicable openRewriteRecipe: |- type: specs.openrewrite.org/v1beta/recipe @@ -187,7 +181,6 @@ description: Remove redundant @ConstructorBinding annotations when applicable recipeList: - org.openrewrite.java.spring.boot3.RemoveConstructorBindingAnnotation - - type: org.springframework.sbm.engine.recipe.OpenRewriteNamedRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -199,7 +192,7 @@ condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject versionPattern: "3\\.0\\..*" - description: Add CrudRepository interface extension additionaly to PagingAndSortingRepository + description: Add CrudRepository interface extension additionally to PagingAndSortingRepository openRewriteRecipe: |- type: specs.openrewrite.org/v1beta/recipe name: org.springframework.sbm.boot.upgrade_27_30.SpringBootPropertiesManual_2_7CrudRepo @@ -215,7 +208,6 @@ - org.springframework.sbm.boot.upgrade_27_30.CrudRepositoryExtension: pagingAndSortingRepository: org.springframework.data.repository.reactive.RxJava3SortingRepository targetCrudRepository: org.springframework.data.repository.reactive.RxJava3CrudRepository - - type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter condition: type: org.springframework.sbm.boot.common.conditions.IsSpringBootProject @@ -324,7 +316,6 @@ - org.openrewrite.properties.ChangePropertyKey: oldPropertyKey: spring.datasource.sql-script-encoding newPropertyKey: spring.sql.init.encoding - - org.openrewrite.yaml.ChangePropertyKey: oldPropertyKey: spring.elasticsearch.rest.connection-timeout newPropertyKey: spring.elasticsearch.connection-timeout @@ -452,7 +443,6 @@ propertyKey: spring.activemq.user - org.openrewrite.properties.DeleteProperty: propertyKey: spring.activemq.user - - org.openrewrite.yaml.DeleteProperty: propertyKey: spring.artemis.pool.block-if-full - org.openrewrite.properties.DeleteProperty: @@ -485,7 +475,6 @@ propertyKey: spring.artemis.pool.use-anonymous-producers - org.openrewrite.properties.DeleteProperty: propertyKey: spring.artemis.pool.use-anonymous-producers - - org.openrewrite.yaml.DeleteProperty: propertyKey: spring.cache.ehcache.config - org.openrewrite.properties.DeleteProperty: @@ -606,7 +595,6 @@ propertyKey: spring.graphql.websocket.path - org.openrewrite.properties.DeleteProperty: propertyKey: spring.graphql.websocket.path - - org.openrewrite.yaml.DeleteProperty: propertyKey: spring.jta.atomikos.properties.allow-sub-transactions - org.openrewrite.properties.DeleteProperty: @@ -687,7 +675,6 @@ propertyKey: spring.jta.log-dir - org.openrewrite.properties.DeleteProperty: propertyKey: spring.jta.log-dir - - type: org.springframework.sbm.boot.properties.actions.AddSpringBootApplicationPropertiesAction description: "Adds default spring boot properties to project. For multi-module project, adds default spring boot properties to every module with jar packaging" condition: @@ -702,6 +689,4 @@ - type: org.springframework.sbm.boot.upgrade_27_30.actions.Boot_27_30_JmxEndpointExposureAction description: "Sets JMX endpoint exposure include to *" condition: - type: org.springframework.sbm.boot.upgrade_27_30.conditions.JmxEndpointExposureCondition - - + type: org.springframework.sbm.boot.upgrade_27_30.conditions.JmxEndpointExposureCondition \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/RemoveImageBannerTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/RemoveImageBannerTest.java new file mode 100644 index 000000000..5a8945536 --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/RemoveImageBannerTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm.boot.upgrade_27_30; + +import org.junit.jupiter.api.Test; +import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportActionDeserializer; +import org.springframework.sbm.build.impl.MavenBuildFileUtil; +import org.springframework.sbm.build.util.PomBuilder; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapterTest; +import org.springframework.sbm.engine.recipe.Recipe; +import org.springframework.sbm.project.resource.TestProjectContext; +import org.springframework.sbm.test.RecipeTestSupport; + +import java.nio.file.FileSystems; +import java.nio.file.Path; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Fabian Krüger + */ +public class RemoveImageBannerTest { + @Test + void testGlobExpression() { + String pattern = "{**/src,src}/main/resources/banner.{gif,png,jpg}"; + assertThat(FileSystems.getDefault().getPathMatcher("glob:"+pattern).matches(Path.of("src/main/resources/banner.gif"))).isTrue(); + assertThat(FileSystems.getDefault().getPathMatcher("glob:"+pattern).matches(Path.of("/src/main/resources/banner.gif"))).isTrue(); + assertThat(FileSystems.getDefault().getPathMatcher("glob:"+pattern).matches(Path.of("some/path/above/src/main/resources/banner.gif"))).isTrue(); + } + + @Test + void applyRemoveImageBannerRecipeShouldRemoveAllImageBannerAtDefaultLocation() { + String parentPom = PomBuilder + .buiildPom("com.example:parent:1.0") + .withModules("moduleA", "moduleB", "moduleC") + .build(); + String moduleA = PomBuilder.buiildPom("com.example:parent:1.0", "moduleA").build(); + String moduleB = PomBuilder.buiildPom("com.example:parent:1.0", "moduleB").build(); + String moduleC = PomBuilder.buiildPom("com.example:parent:1.0", "moduleC").build(); + + ProjectContext context = TestProjectContext.buildProjectContext() + .withMavenBuildFileSource("pom.xml", parentPom) + .withMavenBuildFileSource("moduleA/pom.xml", moduleA) + .addProjectResource("moduleA/src/main/resources/banner.jpg", "") + .withMavenBuildFileSource("moduleB/pom.xml", moduleB) + .addProjectResource("moduleB/src/main/resources/banner.png", "") + .withMavenBuildFileSource("moduleC/pom.xml", moduleC) + .addProjectResource("moduleC/src/main/resources/banner.gif", "") + .build(); + + assertThat(context.getProjectResources().list()).hasSize(7); + + RecipeTestSupport.testRecipe(Path.of("recipes/27_30/migration/sbu30-remove-image-banner.yaml"), recipes -> { + Recipe recipe = recipes.getRecipeByName("sbu30-remove-image-banner").get(); + recipe.apply(context); + + assertThat(context.getProjectResources().list()).hasSize(4); // only pom.xml left + assertThat(context.getProjectResources().stream().allMatch(res -> res.getAbsolutePath().toString().endsWith("pom.xml"))).isTrue(); + }, SpringBootUpgradeReportActionDeserializer.class); + } +} diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportActionTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportActionTest.java index 72f86eb00..b947501f7 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportActionTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportActionTest.java @@ -203,7 +203,7 @@ void verifyRenderedHtml(@TempDir Path tempDir) throws IOException { .serializeProjectContext(tempDir); RecipeIntegrationTestSupport.initializeProject(tempDir, "spring-upgrade-report") - .andApplyRecipe("boot-2.7-3.0-upgrade-report2"); + .andApplyRecipe("sbu30-report"); try (final WebClient webClient = new WebClient()) { webClient.getOptions().setThrowExceptionOnScriptError(false); diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportTestSupport.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportTestSupport.java index 9f19214a2..69b015b4d 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportTestSupport.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportTestSupport.java @@ -19,7 +19,6 @@ import lombok.Setter; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectContextHolder; -import org.springframework.sbm.engine.recipe.Action; import org.springframework.sbm.engine.recipe.Recipe; import org.springframework.sbm.engine.recipe.Recipes; import org.springframework.sbm.project.resource.TestProjectContext; @@ -29,6 +28,7 @@ import org.stringtemplate.v4.ST; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -115,7 +115,7 @@ private void verifyDoesNotRender() { if(SectionBuilderData.class.isInstance(builderData)) { SectionBuilderData sectionBuilderData = SectionBuilderData.class.cast(builderData); withRecipes(recipes -> { - Recipe recipe = recipes.getRecipeByName("boot-2.7-3.0-upgrade-report2").get(); + Recipe recipe = recipes.getRecipeByName("sbu30-report").get(); SpringBootUpgradeReportAction action = (SpringBootUpgradeReportAction) recipe.getActions().get(0); List sections = (List) ReflectionTestUtils.getField(recipe.getActions().get(0), "sections"); List matchingSections = sections @@ -134,7 +134,7 @@ private void verifyDoesNotRender() { } else if(ReportBuilderData.class.isInstance(builderData)) { ReportBuilderData reportBuilderData = ReportBuilderData.class.cast(builderData); withRecipes(recipes -> { - Recipe recipe = recipes.getRecipeByName("boot-2.7-3.0-upgrade-report2").get(); + Recipe recipe = recipes.getRecipeByName("sbu30-report").get(); SpringBootUpgradeReportAction action = (SpringBootUpgradeReportAction) recipe.apply(reportBuilderData.getContext()).get(0); bruteForceProjectContextIntoProjectContextHolder(reportBuilderData.getContext(), action); List sections = (List) ReflectionTestUtils.getField(recipe.getActions().get(0), "sections"); @@ -159,7 +159,7 @@ private void verify(Consumer assertion) { if(ReportBuilderData.class.isInstance(builderData)) { ReportBuilderData reportBuilderData = ReportBuilderData.class.cast(builderData); withRecipes(recipes -> { - Recipe recipe = recipes.getRecipeByName("boot-2.7-3.0-upgrade-report2").get(); + Recipe recipe = recipes.getRecipeByName("sbu30-report").get(); SpringBootUpgradeReportAction action = (SpringBootUpgradeReportAction) recipe.getActions().get(0); bruteForceProjectContextIntoProjectContextHolder(builderData.getContext(), action); // ReflectionTestUtils.setField(action, "upgradeReportProcessor", (SpringBootUpgradeReportFileSystemRenderer) s -> assertion.accept(s)); @@ -167,7 +167,7 @@ private void verify(Consumer assertion) { }); } else if(SectionBuilderData.class.isInstance(builderData)) { withRecipes(recipes -> { - Recipe recipe = recipes.getRecipeByName("boot-2.7-3.0-upgrade-report2").get(); + Recipe recipe = recipes.getRecipeByName("sbu30-report").get(); SpringBootUpgradeReportAction action = (SpringBootUpgradeReportAction) recipe.getActions().get(0); bruteForceProjectContextIntoProjectContextHolder(builderData.getContext(), action); List sections = (List) ReflectionTestUtils.getField(recipe.getActions().get(0), "sections"); @@ -183,7 +183,7 @@ private void verify(Consumer assertion) { SpringBootUpgradeReportSection sectionUnderTest = matchingSections.get(0); action.apply(builderData.getContext()); String renderedSection = sectionUnderTest.render(builderData.getContext()); - String renderedSectionWithoutButtonCode = replaceRe4cipeButtonCodeFromExpectedOutput(sectionUnderTest, renderedSection); + String renderedSectionWithoutButtonCode = replaceRecipeButtonCodeFromExpectedOutput(sectionUnderTest, renderedSection); assertion.accept(renderedSectionWithoutButtonCode); }); @@ -194,32 +194,42 @@ private void verify(Consumer assertion) { * Another hack, removing the expected button code added to the Asciidoc to free tests from asserting invisible * code of buttons to apply a recipe. */ - private String replaceRe4cipeButtonCodeFromExpectedOutput(SpringBootUpgradeReportSection sectionUnderTest, String renderedSection) { - StringBuilder sb = new StringBuilder(); - List buttonCodes = sectionUnderTest - .getRemediation() - .getPossibilities() - .stream() - .filter(p -> p.getRecipe() != null) - .map(RemediationPossibility::getRecipe) - .map(recipe -> { - String target = """ + private String replaceRecipeButtonCodeFromExpectedOutput(SpringBootUpgradeReportSection sectionUnderTest, String renderedSection) { + List buttonCodes = new ArrayList<>(); + if(sectionUnderTest.getRemediation().getPossibilities().isEmpty()) { + String recipe = sectionUnderTest.getRemediation().getRecipe(); + if(recipe != null) { + String target = """ - ++++ -
- - -
- ++++ + ++++ +
+
+ ++++ - """; - return target.replace("", recipe); - }) - .collect(Collectors.toList()); + """; + buttonCodes.add(target.replace("", recipe)); + } + } else { + buttonCodes = sectionUnderTest + .getRemediation() + .getPossibilities() + .stream() + .filter(p -> p.getRecipe() != null) + .map(RemediationPossibility::getRecipe) + .map(recipe -> { + String target = """ + + ++++ +
+
+ ++++ + + """; + return target.replace("", recipe); + }) + .collect(Collectors.toList()); + } + for(String buttonCode : buttonCodes) { renderedSection = renderedSection.replace(buttonCode, ""); } @@ -228,7 +238,7 @@ private String replaceRe4cipeButtonCodeFromExpectedOutput(SpringBootUpgradeRepor private void withRecipes(Consumer recipesConsumer) { RecipeTestSupport.testRecipe( - Path.of("recipes/boot-new-report.yaml"), recipesConsumer, + Path.of("recipes/27_30/report/sbu30-report.yaml"), recipesConsumer, SpringBootUpgradeReportActionDeserializer.class, SpringBootUpgradeReportFreemarkerSupport.class, SpringBootUpgradeReportFileSystemRenderer.class, @@ -237,9 +247,14 @@ private void withRecipes(Consumer recipesConsumer) { } private String replacePlaceHolders(String expectedOutput, Map templateVariables) { - ST st = new ST(expectedOutput); - templateVariables.entrySet().stream().forEach(e -> st.add(e.getKey(), e.getValue())); - return st.render(); + StringBuffer sb = new StringBuffer(); + // hacked, there's most probably a better way but ST couldn't digest html code + for(Map.Entry kv : templateVariables.entrySet()) { + String key = "<" + kv.getKey() + ">"; + String replacement = kv.getValue(); + expectedOutput = expectedOutput.replace(key, replacement); + } + return expectedOutput; } } diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java index 2ead487b8..2b8b8f1d3 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/BannerSupportReportSectionTest.java @@ -37,23 +37,43 @@ public void rendersBannerSupportInformation() { .fromProjectContext(context) .shouldRenderAs( """ - === Banner support - Issue: https://github.com/spring-projects-experimental/spring-boot-migrator/issues/150[#150], Contributors: https://github.com/sanagaraj-pivotal[@sanagaraj-pivotal^, role="ext-link"] - - ==== What Changed - Support for image-based application banners has been removed. banner.gif, banner.jpg, and banner.png - files are now ignored and should be replaced with a text-based banner.txt file. - - ==== Why is the application affected - The scan found banner image files here: - - * /src/main/resources/banner.gif - * /src/main/resources/banner.jpg - - ==== Remediation - remove image banners and replace it with text-banner with banner.txt file - - - """); + === Banner support + Issue: https://github.com/spring-projects-experimental/spring-boot-migrator/issues/150[#150], Contributors: https://github.com/fabapp2[@fabapp2^, role="ext-link"], https://github.com/sanagaraj-pivotal[@sanagaraj-pivotal^, role="ext-link"] + + ==== What Changed + Support for image-based application banners has been removed. banner.gif, banner.jpg, and banner.png + files are now ignored and should be replaced with a text-based banner.txt file. + + ==== Why is the application affected + The scan found banner image files here: + + * `/src/main/resources/banner.gif` + * `/src/main/resources/banner.jpg` + + ==== Remediation + + + ===== Remove image banner + Remove these image banners\s + + * `/src/main/resources/banner.gif` + * `/src/main/resources/banner.jpg` + + + + ++++ +
+
+ ++++ + ===== Replace image banner + Replace these banners\s + + * `/src/main/resources/banner.gif` + * `/src/main/resources/banner.jpg` + + with `banner.txt` + + + """); } } diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelperTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelperTest.java index 627c0f804..d8d69ad16 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelperTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/PagingAndSortingHelperTest.java @@ -46,6 +46,7 @@ public class A {} """; ProjectContext context = TestProjectContext.buildProjectContext() + .withSpringBootParentOf("2.7.1") .addJavaSource("src/main/java", javaClassWithPagingAndSortingRepository) .addJavaSource("src/main/java",javaClassWithoutPagingAndSortingRepo) .withBuildFileHavingDependencies("org.springframework.data:spring-data-commons:2.7.1") @@ -105,6 +106,7 @@ public class A {} """; ProjectContext context = TestProjectContext.buildProjectContext() + .withSpringBootParentOf("2.7.1") .addJavaSource("src/main/java", javaClassWithReactiveSortingRepo) .addJavaSource("src/main/java",javaClassWithoutReactiveSortingRepo) .withBuildFileHavingDependencies("org.springframework.data:spring-data-commons:2.7.1") @@ -165,6 +167,7 @@ public class A {} """; ProjectContext context = TestProjectContext.buildProjectContext() + .withSpringBootParentOf("2.7.1") .addJavaSource("src/main/java", javaClassWithReactiveSortingRepo) .addJavaSource("src/main/java",javaClassWithoutReactiveSortingRepo) .withBuildFileHavingDependencies("org.springframework.data:spring-data-commons:2.7.1") @@ -249,6 +252,7 @@ public class A {} """; ProjectContext context = TestProjectContext.buildProjectContext() + .withSpringBootParentOf("2.7.1") .addJavaSource("src/main/java", javaClassWithPagingAndSortingRepository) .addJavaSource("src/main/java",javaClassWithoutPagingAndSortingRepo) .addJavaSource("src/main/java",javaClassWithReactiveSortingRepo) @@ -308,6 +312,7 @@ public class A {} """; ProjectContext context = TestProjectContext.buildProjectContext() + .withSpringBootParentOf("2.7.1") .addJavaSource("src/main/java",javaClassWithoutPagingAndSortingRepo) .withBuildFileHavingDependencies("org.springframework.data:spring-data-commons:2.7.1") .build(); diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java index 98ff5d88e..e6b46aab6 100644 --- a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/SpringMVCAndWebFluxUrlMatchingChangesReportSectionTest.java @@ -105,8 +105,8 @@ public void configurePathMatch(PathMatchConfigurer configurer) { ==== Why is the application affected The scan found classes annotated with `@RestController` which could be affected by this change. - * file:///src/main/java/a/example/RestController2.java[`src/main/java/a/example/RestController2.java`]<#lt> - * file:///src/main/java/b/example/RestController1.java[`src/main/java/b/example/RestController1.java`]<#lt> + * file:///src/main/java/a/example/RestController2.java[`src/main/java/a/example/RestController2.java`] + * file:///src/main/java/b/example/RestController1.java[`src/main/java/b/example/RestController1.java`] ==== Remediation You have different choices to remediate this change. @@ -152,8 +152,6 @@ public void configurePathMatch(PathMatchConfigurer configurer) { } .... - sbu30-248-add-PathMatchConfigurer - """; diff --git a/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeDepenenciesMigrationTest.java b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeDepenenciesMigrationTest.java new file mode 100644 index 000000000..413f6c21e --- /dev/null +++ b/components/sbm-recipes-boot-upgrade/src/test/java/org/springframework/sbm/boot/upgrade_27_30/report/helper/UpgradeDepenenciesMigrationTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2021 - 2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.sbm.boot.upgrade_27_30.report.helper; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.openrewrite.maven.MavenParser; +import org.openrewrite.xml.tree.Xml; +import org.springframework.sbm.engine.context.ProjectContext; +import org.springframework.sbm.engine.recipe.Recipe; +import org.springframework.sbm.project.resource.TestProjectContext; +import org.springframework.sbm.test.RecipeTestSupport; + +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Fabian Krüger + */ +public class UpgradeDepenenciesMigrationTest { + @Test + void migrateEhCacheToSpringBoot3() { + ProjectContext context = TestProjectContext.buildProjectContext() + .withSpringBootParentOf("2.7.5") + .withBuildFileHavingDependencies("org.ehcache:ehcache") + .build(); + + System.out.println(context.getBuildFile().print()); + + RecipeTestSupport.testRecipe(Path.of("recipes/27_30/migration/sbu30-upgrade-dependencies.yaml"), recipes -> { + Recipe recipe = recipes.getRecipeByName("sbu30-upgrade-dependencies").get(); + recipe.apply(context); + String modifiedPom = context.getApplicationModules().getRootModule().getBuildFile().print(); + assertThat(modifiedPom).isEqualTo( + """ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.5 + + + com.example + dummy-root + 0.1.0-SNAPSHOT + jar + + + org.ehcache + ehcache + 3.10.2 + jakarta + + + + """ + ); + Xml.Document document = MavenParser.builder().build().parse(modifiedPom).get(0); + assertThat(document).isNotNull(); + }); + } +} diff --git a/demos/spring-boot-3-upgrade-demo/.gitignore b/demos/spring-boot-3-upgrade-demo/.gitignore new file mode 100644 index 000000000..25d0b65e5 --- /dev/null +++ b/demos/spring-boot-3-upgrade-demo/.gitignore @@ -0,0 +1 @@ +/demo-spring-song-app/ diff --git a/demos/spring-boot-3-upgrade-demo/run-demo.sh b/demos/spring-boot-3-upgrade-demo/run-demo.sh new file mode 100644 index 000000000..73a63dc2c --- /dev/null +++ b/demos/spring-boot-3-upgrade-demo/run-demo.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +scriptDir=$(dirname "${BASH_SOURCE[0]}") +projectRoot=$scriptDir/../.. +webApp=$projectRoot/applications/spring-boot-upgrade +demoApp="$scriptDir/demo-spring-song-app" +applicationJar="${webApp}/target/spring-boot-upgrade.jar" + +function pause(){ + echo "==============================================================================================" + echo " -> $*" + echo " Press Enter to continue..." + read -p "==============================================================================================" +} + +function build() { + # build sbm + pushd "${projectRoot}" || exit + mvn clean install -DskipTests + popd +} + +function buildIfGitStatusNotClean() { + git update-index --really-refresh >> /dev/null + if [[ ! `git diff-index --quiet HEAD` ]] || [[ ! -f "${webApp}/target/spring-boot-upgrade.jar" ]]; then + echo "git status not clean, building project" + build + fi +} + + +# cleanup +rm -rf "$demoApp" + +buildIfGitStatusNotClean + +# checkout demo project +git clone https://github.com/sanagaraj-pivotal/demo-spring-song-app.git $demoApp +pushd "$demoApp" || exit +git checkout -b boot-3-upgrade-demo tags/demo +idea . +popd + +pause "kill process currently running under port 8080" +lsof -i :8080 | awk '{system("kill -9 " $2)}' + +# start webapp +java -jar --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED $applicationJar $demoApp diff --git a/applications/rest-service/src/main/resources/application.properties b/demos/webapp-demo/song-app.http similarity index 100% rename from applications/rest-service/src/main/resources/application.properties rename to demos/webapp-demo/song-app.http diff --git a/pom.xml b/pom.xml index d17e09792..5459a66a4 100644 --- a/pom.xml +++ b/pom.xml @@ -311,7 +311,7 @@ applications/spring-shell - applications/rest-service + applications/spring-boot-upgrade components/openrewrite-spring-recipes components/sbm-recipes-boot-upgrade components/sbm-recipes-spring-cloud