diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 96a0234..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# Require maintainer's :+1: for changes to the .github/ repo-config files -# mainly due to https://github.com/probot/settings privilege escalation -.github/* @pages-themes/maintainers diff --git a/.github/config.yml b/.github/config.yml deleted file mode 100644 index 683f93f..0000000 --- a/.github/config.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Behaviorbot config. See https://github.com/behaviorbot/ for more information. -# Note: Please Don't edit this file directly. -# Edit https://github.com/pages-themes/maintenance-scripts instead. - -# Configuration for update-docs - https://github.com/behaviorbot/update-docs -updateDocsComment: "Thanks for the pull request! If you are making any changes to the user-facing functionality, please be sure to update the documentation in the `README` or `docs/` folder alongside your change. :heart:" - -# Configuration for request-info - https://github.com/behaviorbot/request-info -requestInfoReplyComment: Thanks for this. Do you mind providing a bit more information about what problem you're trying to solve? -requestInfoLabelToAdd: more-information-needed - -# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome -#newIssueWelcomeComment: > -# Welcome! - -# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome -newPRWelcomeComment: Welcome! Congrats on your first pull request to The Cayman Theme. If you haven't already, please be sure to check out [the contributing guidelines](https://github.com/pages-themes/cayman/blob/master/docs/CONTRIBUTING.md). - -# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge -firstPRMergeComment: "Congrats on getting your first pull request to The Cayman Theme merged! Without amazing humans like you submitting pull requests, we couldn’t run this project. You rock! :tada:

If you're interested in tackling another bug or feature, take a look at [the open issues](https://github.com/pages-themes/cayman/issues), especially those [labeled `help wanted`](https://github.com/pages-themes/cayman/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)." diff --git a/.github/no-response.yml b/.github/no-response.yml deleted file mode 100644 index 7193eaa..0000000 --- a/.github/no-response.yml +++ /dev/null @@ -1,13 +0,0 @@ -# Configuration for probot-no-response - https://github.com/probot/no-response - -# Number of days of inactivity before an Issue is closed for lack of response -daysUntilClose: 14 -# Label requiring a response -responseRequiredLabel: more-information-needed -# Comment to post when closing an Issue for lack of response. Set to `false` to disable -closeComment: > - This issue has been automatically closed because there has been no response - to our request for more information from the original author. With only the - information that is currently in the issue, we don't have enough information - to take action. Please reach out if you have or find the answers we need so - that we can investigate further. diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index a1aa17e..0000000 --- a/.github/stale.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 60 - -# Number of days of inactivity before a stale Issue or Pull Request is closed -daysUntilClose: 7 - -# Issues or Pull Requests with these labels will never be considered stale -exemptLabels: - - pinned - - security - -# Label to use when marking as stale -staleLabel: wontfix - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. - -# Comment to post when closing a stale Issue or Pull Request. Set to `false` to disable -closeComment: false - -# Limit to only `issues` or `pulls` -# only: issues diff --git a/.gitignore b/.gitignore index ab21548..dcaa5c6 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,7 @@ local.properties .settings/ .loadpath .factorypath -/src/main/resources/rebel.xml +/src/docs/resources/rebel.xml # External tool builders .externalToolBuilders/** diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index 648dfb1..0000000 --- a/.rubocop.yml +++ /dev/null @@ -1,6 +0,0 @@ -AllCops: - Exclude: - - _site/**/* - -Metrics/LineLength: - Enabled: false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 412d52e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: java -jdk: - - openjdk8 -cache: - directories: - - $HOME/.m2 - - $HOME/.sonar/cache - -script: - - mvn clean package diff --git a/CNAME b/CNAME deleted file mode 100644 index 30f0619..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -springdoc.org \ No newline at end of file diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 7f4f5e9..0000000 --- a/Gemfile +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -source 'https://rubygems.org' - -gemspec diff --git a/LICENSE b/LICENSE index 670154e..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,116 +1,201 @@ -CC0 1.0 Universal - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator and -subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for the -purpose of contributing to a commons of creative, cultural and scientific -works ("Commons") that the public can reliably and without fear of later -claims of infringement build upon, modify, incorporate in other works, reuse -and redistribute as freely as possible in any form whatsoever and for any -purposes, including without limitation commercial purposes. These owners may -contribute to the Commons to promote the ideal of a free culture and the -further production of creative, cultural and scientific works, or to gain -reputation or greater distribution for their Work in part through the use and -efforts of others. - -For these and/or other purposes and motivations, and without any expectation -of additional consideration or compensation, the person associating CC0 with a -Work (the "Affirmer"), to the extent that he or she is an owner of Copyright -and Related Rights in the Work, voluntarily elects to apply CC0 to the Work -and publicly distribute the Work under its terms, with knowledge of his or her -Copyright and Related Rights in the Work and the meaning and intended legal -effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not limited -to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, communicate, - and translate a Work; - - ii. moral rights retained by the original author(s) and/or performer(s); - - iii. publicity and privacy rights pertaining to a person's image or likeness - depicted in a Work; - - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - - v. rights protecting the extraction, dissemination, use and reuse of data in - a Work; - - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation thereof, - including any amended or successor version of such directive); and - - vii. other similar, equivalent or corresponding rights throughout the world - based on applicable law or treaty, and any national implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention of, -applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and -unconditionally waives, abandons, and surrenders all of Affirmer's Copyright -and Related Rights and associated claims and causes of action, whether now -known or unknown (including existing as well as future claims and causes of -action), in the Work (i) in all territories worldwide, (ii) for the maximum -duration provided by applicable law or treaty (including future time -extensions), (iii) in any current or future medium and for any number of -copies, and (iv) for any purpose whatsoever, including without limitation -commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes -the Waiver for the benefit of each member of the public at large and to the -detriment of Affirmer's heirs and successors, fully intending that such Waiver -shall not be subject to revocation, rescission, cancellation, termination, or -any other legal or equitable action to disrupt the quiet enjoyment of the Work -by the public as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason be -judged legally invalid or ineffective under applicable law, then the Waiver -shall be preserved to the maximum extent permitted taking into account -Affirmer's express Statement of Purpose. In addition, to the extent the Waiver -is so judged Affirmer hereby grants to each affected person a royalty-free, -non transferable, non sublicensable, non exclusive, irrevocable and -unconditional license to exercise Affirmer's Copyright and Related Rights in -the Work (i) in all territories worldwide, (ii) for the maximum duration -provided by applicable law or treaty (including future time extensions), (iii) -in any current or future medium and for any number of copies, and (iv) for any -purpose whatsoever, including without limitation commercial, advertising or -promotional purposes (the "License"). The License shall be deemed effective as -of the date CC0 was applied by Affirmer to the Work. Should any part of the -License for any reason be judged legally invalid or ineffective under -applicable law, such partial invalidity or ineffectiveness shall not -invalidate the remainder of the License, and in such case Affirmer hereby -affirms that he or she will not (i) exercise any of his or her remaining -Copyright and Related Rights in the Work or (ii) assert any associated claims -and causes of action with respect to the Work, in either case contrary to -Affirmer's express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - - b. Affirmer offers the Work as-is and makes no representations or warranties - of any kind concerning the Work, express, implied, statutory or otherwise, - including without limitation warranties of title, merchantability, fitness - for a particular purpose, non infringement, or the absence of latent or - other defects, accuracy, or the present or absence of errors, whether or not - discoverable, all to the greatest extent permissible under applicable law. - - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without limitation - any person's Copyright and Related Rights in the Work. Further, Affirmer - disclaims responsibility for obtaining any necessary consents, permissions - or other rights required for any use of the Work. - - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to this - CC0 or use of the Work. - -For more information, please see - + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/README.md b/README.md deleted file mode 100644 index fe78437..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# springdoc.github.io -Library for OpenAPI 3 with spring-boot -[![Build Status](https://api.travis-ci.org/springdoc/springdoc.github.io.svg?branch=master)](https://travis-ci.org/springdoc/springdoc.github.io) - -# [Full documentation](https://springdoc.org) diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 7db9f17..0000000 --- a/_config.yml +++ /dev/null @@ -1,7 +0,0 @@ -title: springdoc-openapi -description: Library for OpenAPI 3 with spring-boot -google_analytics: UA-143834491-1 -theme: jekyll-theme-cayman -url: http://springdoc.org -show_downloads: true -markdown: kramdown \ No newline at end of file diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100644 index 31ee2b7..0000000 --- a/_layouts/default.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - {% if site.google_analytics %} - - - {% endif %} - - -{% seo %} - - - - - - - Skip to the content. - - - -
- {{ content }} - - -
- - diff --git a/_sass/jekyll-theme-cayman.scss b/_sass/jekyll-theme-cayman.scss deleted file mode 100644 index b9a93db..0000000 --- a/_sass/jekyll-theme-cayman.scss +++ /dev/null @@ -1,378 +0,0 @@ -@import "normalize"; -@import "rouge-github"; -@import "variables"; -@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); - -@mixin large { - @media screen and (min-width: #{$large-breakpoint}) { - @content; - } -} - -@mixin medium { - @media screen and (min-width: #{$medium-breakpoint}) and (max-width: #{$large-breakpoint}) { - @content; - } -} - -@mixin small { - @media screen and (max-width: #{$medium-breakpoint}) { - @content; - } -} - -* { - box-sizing: border-box; -} - -body { - padding: 0; - margin: 0; - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 1.5; - color: $body-text-color; -} - -#skip-to-content { - height: 1px; - width: 1px; - position: absolute; - overflow: hidden; - top: -10px; - - &:focus { - position: fixed; - top: 10px; - left: 10px; - height: auto; - width: auto; - background: invert($body-link-color); - outline: thick solid invert($body-link-color); - } -} - -a { - color: $body-link-color; - text-decoration: none; - - &:hover { - text-decoration: underline; - } -} - -.btn { - display: inline-block; - margin-bottom: 1rem; - color: rgba(255, 255, 255, 0.7); - background-color: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.2); - border-style: solid; - border-width: 1px; - border-radius: 0.3rem; - transition: color 0.2s, background-color 0.2s, border-color 0.2s; - - &:hover { - color: rgba(255, 255, 255, 0.8); - text-decoration: none; - background-color: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.3); - } - - + .btn { - margin-left: 1rem; - } - - @include large { - padding: 0.75rem 1rem; - } - - @include medium { - padding: 0.6rem 0.9rem; - font-size: 0.9rem; - } - - @include small { - display: block; - width: 100%; - padding: 0.75rem; - font-size: 0.9rem; - - + .btn { - margin-top: 1rem; - margin-left: 0; - } - } -} - -.page-header { - color: $header-heading-color; - text-align: center; - background-color: $header-bg-color; - background-image: linear-gradient(120deg, #155799, #171918); - - @include large { - padding: 1rem 1rem; - } - - @include medium { - padding: 2rem 2rem; - } - - @include small { - padding: 3rem 1rem; - } -} - -.project-name { - margin-top: 0; - margin-bottom: 0.1rem; - - @include large { - font-size: 3.25rem; - } - - @include medium { - font-size: 2.25rem; - } - - @include small { - font-size: 1.75rem; - } -} - -.project-tagline { - margin-bottom: 2rem; - font-weight: normal; - opacity: 0.7; - - @include large { - font-size: 1.25rem; - } - - @include medium { - font-size: 1.15rem; - } - - @include small { - font-size: 1rem; - } -} - -.main-content { - word-wrap: break-word; - - :first-child { - margin-top: 0; - } - - @include large { - max-width: 64rem; - padding: 2rem 6rem; - margin: 0 auto; - font-size: 1.1rem; - } - - @include medium { - padding: 2rem 4rem; - font-size: 1.1rem; - } - - @include small { - padding: 2rem 1rem; - font-size: 1rem; - } - - kbd { - background-color: #fafbfc; - border: 1px solid #c6cbd1; - border-bottom-color: #959da5; - border-radius: 3px; - box-shadow: inset 0 -1px 0 #959da5; - color: #444d56; - display: inline-block; - font-size: 11px; - line-height: 10px; - padding: 3px 5px; - vertical-align: middle; - } - - img { - max-width: 100%; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - margin-top: 2rem; - margin-bottom: 1rem; - font-weight: normal; - color: $section-headings-color; - } - - p { - margin-bottom: 1em; - } - - code { - padding: 2px 4px; - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 0.9rem; - color: $code-text-color; - background-color: $code-bg-color; - border-radius: 0.3rem; - } - - pre { - padding: 0.8rem; - margin-top: 0; - margin-bottom: 1rem; - font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace; - color: $code-text-color; - word-wrap: normal; - background-color: $code-bg-color; - border: solid 1px $border-color; - border-radius: 0.3rem; - - > code { - padding: 0; - margin: 0; - font-size: 0.9rem; - color: $code-text-color; - word-break: normal; - white-space: pre; - background: transparent; - border: 0; - } - } - - .highlight { - margin-bottom: 1rem; - - pre { - margin-bottom: 0; - word-break: normal; - } - } - - .highlight pre, - pre { - padding: 0.8rem; - overflow: auto; - font-size: 0.9rem; - line-height: 1.45; - border-radius: 0.3rem; - -webkit-overflow-scrolling: touch; - } - - pre code, - pre tt { - display: inline; - max-width: initial; - padding: 0; - margin: 0; - overflow: initial; - line-height: inherit; - word-wrap: normal; - background-color: transparent; - border: 0; - - &:before, - &:after { - content: normal; - } - } - - ul, - ol { - margin-top: 0; - } - - blockquote { - padding: 0 1rem; - margin-left: 0; - color: $blockquote-text-color; - border-left: 0.3rem solid $border-color; - - > :first-child { - margin-top: 0; - } - - > :last-child { - margin-bottom: 0; - } - } - - table { - display: block; - width: 100%; - overflow: auto; - word-break: normal; - word-break: keep-all; // For Firefox to horizontally scroll wider tables. - -webkit-overflow-scrolling: touch; - - th { - font-weight: bold; - } - - th, - td { - padding: 0.5rem 1rem; - border: 1px solid $table-border-color; - } - } - - dl { - padding: 0; - - dt { - padding: 0; - margin-top: 1rem; - font-size: 1rem; - font-weight: bold; - } - - dd { - padding: 0; - margin-bottom: 1rem; - } - } - - hr { - height: 2px; - padding: 0; - margin: 1rem 0; - background-color: $hr-border-color; - border: 0; - } -} - -.site-footer { - padding-top: 2rem; - margin-top: 2rem; - border-top: solid 1px $hr-border-color; - - @include large { - font-size: 1rem; - } - - @include medium { - font-size: 1rem; - } - - @include small { - font-size: 0.9rem; - } -} - -.site-footer-owner { - display: block; - font-weight: bold; -} - -.site-footer-credits { - color: $blockquote-text-color; -} diff --git a/_sass/normalize.scss b/_sass/normalize.scss deleted file mode 100644 index 30366a6..0000000 --- a/_sass/normalize.scss +++ /dev/null @@ -1,424 +0,0 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ - -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ - -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ - -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ - -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ - -/** - * Remove the gray background color from active links in IE 10. - */ - -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ - -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Remove border when inside `a` element in IE 8/9/10. - */ - -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ - -/** - * Address margin not present in IE 8/9 and Safari. - */ - -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ - -hr { - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ - -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ - -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ - -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ - -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ - -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ - -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ - -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} diff --git a/_sass/rouge-github.scss b/_sass/rouge-github.scss deleted file mode 100644 index daf76ad..0000000 --- a/_sass/rouge-github.scss +++ /dev/null @@ -1,209 +0,0 @@ -.highlight table td { padding: 5px; } -.highlight table pre { margin: 0; } -.highlight .cm { - color: #999988; - font-style: italic; -} -.highlight .cp { - color: #999999; - font-weight: bold; -} -.highlight .c1 { - color: #999988; - font-style: italic; -} -.highlight .cs { - color: #999999; - font-weight: bold; - font-style: italic; -} -.highlight .c, .highlight .cd { - color: #999988; - font-style: italic; -} -.highlight .err { - color: #a61717; - background-color: #e3d2d2; -} -.highlight .gd { - color: #000000; - background-color: #ffdddd; -} -.highlight .ge { - color: #000000; - font-style: italic; -} -.highlight .gr { - color: #aa0000; -} -.highlight .gh { - color: #999999; -} -.highlight .gi { - color: #000000; - background-color: #ddffdd; -} -.highlight .go { - color: #888888; -} -.highlight .gp { - color: #555555; -} -.highlight .gs { - font-weight: bold; -} -.highlight .gu { - color: #aaaaaa; -} -.highlight .gt { - color: #aa0000; -} -.highlight .kc { - color: #000000; - font-weight: bold; -} -.highlight .kd { - color: #000000; - font-weight: bold; -} -.highlight .kn { - color: #000000; - font-weight: bold; -} -.highlight .kp { - color: #000000; - font-weight: bold; -} -.highlight .kr { - color: #000000; - font-weight: bold; -} -.highlight .kt { - color: #445588; - font-weight: bold; -} -.highlight .k, .highlight .kv { - color: #000000; - font-weight: bold; -} -.highlight .mf { - color: #009999; -} -.highlight .mh { - color: #009999; -} -.highlight .il { - color: #009999; -} -.highlight .mi { - color: #009999; -} -.highlight .mo { - color: #009999; -} -.highlight .m, .highlight .mb, .highlight .mx { - color: #009999; -} -.highlight .sb { - color: #d14; -} -.highlight .sc { - color: #d14; -} -.highlight .sd { - color: #d14; -} -.highlight .s2 { - color: #d14; -} -.highlight .se { - color: #d14; -} -.highlight .sh { - color: #d14; -} -.highlight .si { - color: #d14; -} -.highlight .sx { - color: #d14; -} -.highlight .sr { - color: #009926; -} -.highlight .s1 { - color: #d14; -} -.highlight .ss { - color: #990073; -} -.highlight .s { - color: #d14; -} -.highlight .na { - color: #008080; -} -.highlight .bp { - color: #999999; -} -.highlight .nb { - color: #0086B3; -} -.highlight .nc { - color: #445588; - font-weight: bold; -} -.highlight .no { - color: #008080; -} -.highlight .nd { - color: #3c5d5d; - font-weight: bold; -} -.highlight .ni { - color: #800080; -} -.highlight .ne { - color: #990000; - font-weight: bold; -} -.highlight .nf { - color: #990000; - font-weight: bold; -} -.highlight .nl { - color: #990000; - font-weight: bold; -} -.highlight .nn { - color: #555555; -} -.highlight .nt { - color: #000080; -} -.highlight .vc { - color: #008080; -} -.highlight .vg { - color: #008080; -} -.highlight .vi { - color: #008080; -} -.highlight .nv { - color: #008080; -} -.highlight .ow { - color: #000000; - font-weight: bold; -} -.highlight .o { - color: #000000; - font-weight: bold; -} -.highlight .w { - color: #bbbbbb; -} -.highlight { - background-color: #f8f8f8; -} diff --git a/_sass/variables.scss b/_sass/variables.scss deleted file mode 100644 index bf56450..0000000 --- a/_sass/variables.scss +++ /dev/null @@ -1,23 +0,0 @@ -// Breakpoints -$large-breakpoint: 64em !default; -$medium-breakpoint: 42em !default; - -// Headers -$header-heading-color: #fff !default; -$header-bg-color: #159957 !default; -$header-bg-color-secondary: #155799 !default; - -// Text -$section-headings-color: #159957 !default; -$body-text-color: #606c71 !default; -$body-link-color: #1e6bb8 !default; -$blockquote-text-color: #819198 !default; - -// Code -$code-bg-color: #f3f6fa !default; -$code-text-color: #567482 !default; - -// Borders -$border-color: #dce6f0 !default; -$table-border-color: #e9ebec !default; -$hr-border-color: #eff0f1 !default; diff --git a/assets/css/style.scss b/assets/css/style.scss deleted file mode 100644 index 3293d74..0000000 --- a/assets/css/style.scss +++ /dev/null @@ -1,54 +0,0 @@ ---- ---- - -@import 'jekyll-theme-cayman'; - -#forkme_banner { - display: block; - position: absolute; - top:0; - right: 10px; - z-index: 10; - padding: 10px 50px 10px 10px; - color: #fff; - background: url('../images/blacktocat.png') #373737 no-repeat 95% 50%; - font-weight: 700; - box-shadow: 0 0 10px rgba(0,0,0,.5); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -table { - border: 1px solid #373737; - margin-bottom: 20px; - text-align: left; - } - -th { - font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; - padding: 10px; - background: #373737; - text-align: center !important; - color: #fff; - } - -td { - padding: 10px; - border: 1px solid #373737; - background-color: #f3f6fa; - } - -table th:first-of-type { - width: 40%; -} -table th:nth-of-type(2) { - width: 20%; -} -table th:nth-of-type(3) { - width: 40%; -} \ No newline at end of file diff --git a/assets/images/blacktocat.png b/assets/images/blacktocat.png deleted file mode 100644 index e160053..0000000 Binary files a/assets/images/blacktocat.png and /dev/null differ diff --git a/assets/images/body-bg.jpg b/assets/images/body-bg.jpg deleted file mode 100644 index 719fb88..0000000 Binary files a/assets/images/body-bg.jpg and /dev/null differ diff --git a/assets/images/download-button.png b/assets/images/download-button.png deleted file mode 100644 index c5ffb3a..0000000 Binary files a/assets/images/download-button.png and /dev/null differ diff --git a/assets/images/github-button.png b/assets/images/github-button.png deleted file mode 100644 index cd41580..0000000 Binary files a/assets/images/github-button.png and /dev/null differ diff --git a/assets/images/header-bg.jpg b/assets/images/header-bg.jpg deleted file mode 100644 index d16497a..0000000 Binary files a/assets/images/header-bg.jpg and /dev/null differ diff --git a/assets/images/highlight-bg.jpg b/assets/images/highlight-bg.jpg deleted file mode 100644 index 355e089..0000000 Binary files a/assets/images/highlight-bg.jpg and /dev/null differ diff --git a/assets/images/jetbrains.svg b/assets/images/jetbrains.svg deleted file mode 100644 index 75d4d21..0000000 --- a/assets/images/jetbrains.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/images/sidebar-bg.jpg b/assets/images/sidebar-bg.jpg deleted file mode 100644 index 536ead9..0000000 Binary files a/assets/images/sidebar-bg.jpg and /dev/null differ diff --git a/assets/images/springdoc-openapi-prez-old.jpg b/assets/images/springdoc-openapi-prez-old.jpg deleted file mode 100644 index 29b3987..0000000 Binary files a/assets/images/springdoc-openapi-prez-old.jpg and /dev/null differ diff --git a/assets/images/springdoc-openapi.png b/assets/images/springdoc-openapi.png deleted file mode 100644 index 7e80992..0000000 Binary files a/assets/images/springdoc-openapi.png and /dev/null differ diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000..c5961d2 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +springdoc.org diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md deleted file mode 100644 index ab1a9a1..0000000 --- a/docs/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at opensource@github.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index dc8bc5f..0000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,88 +0,0 @@ -# Contributing to The Cayman Theme - -Hi there! We're thrilled that you'd like to contribute to The Cayman Theme. Your help is essential for keeping it great. - -The Cayman Theme is an open source project supported by the efforts of an entire community and built one contribution at a time by users like you. We'd love for you to get involved. Whatever your level of skill or however much time you can give, your contribution is greatly appreciated. There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests, helping other users by commenting on issues, or writing code which can be incorporated into The Cayman Theme itself. - -Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue, assessing changes, and helping you finalize your pull requests. - - -## Looking for support? - -We'd love to help. Check out [the support guidelines](SUPPORT.md). - -## How to report a bug - -Think you found a bug? Please check [the list of open issues](https://github.com/pages-themes/cayman/issues) to see if your bug has already been reported. If it hasn't please [submit a new issue](https://github.com/pages-themes/cayman/issues/new). - -Here are a few tips for writing *great* bug reports: - -* Describe the specific problem (e.g., "widget doesn't turn clockwise" versus "getting an error") -* Include the steps to reproduce the bug, what you expected to happen, and what happened instead -* Check that you are using the latest version of the project and its dependencies -* Include what version of the project your using, as well as any relevant dependencies -* Only include one bug per issue. If you have discovered two bugs, please file two issues -* Even if you don't know how to fix the bug, including a failing test may help others track it down - -**If you find a security vulnerability, do not open an issue. Please email security@github.com instead.** - -## How to suggest a feature or enhancement - -If you find yourself wishing for a feature that doesn't exist in The Cayman Theme, you are probably not alone. There are bound to be others out there with similar needs. Many of the features that The Cayman Theme has today have been added because our users saw the need. - -Feature requests are welcome. But take a moment to find out whether your idea fits with the scope and goals of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Please provide as much detail and context as possible, including describing the problem you're trying to solve. - -[Open an issue](https://github.com/pages-themes/cayman/issues/new) which describes the feature you would like to see, why you want it, how it should work, etc. - - - -## Your first contribution - -We'd love for you to contribute to the project. Unsure where to begin contributing to The Cayman Theme? You can start by looking through these "good first issue" and "help wanted" issues: - -* [Good first issues](https://github.com/pages-themes/cayman/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) - issues which should only require a few lines of code and a test or two -* [Help wanted issues](https://github.com/pages-themes/cayman/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) - issues which may be a bit more involved, but are specifically seeking community contributions - -*p.s. Feel free to ask for help; everyone is a beginner at first* :smiley_cat: - -## How to propose changes - -Here's a few general guidelines for proposing changes: - -* If you are making visual changes, include a screenshot of what the affected element looks like, both before and after. -* Follow the [Jekyll style guide](https://ben.balter.com/jekyll-style-guide). -* If you are changing any user-facing functionality, please be sure to update the documentation -* Each pull request should implement **one** feature or bug fix. If you want to add or fix more than one thing, submit more than one pull request -* Do not commit changes to files that are irrelevant to your feature or bug fix -* Don't bump the version number in your pull request (it will be bumped prior to release) -* Write [a good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - -At a high level, [the process for proposing changes](https://guides.github.com/introduction/flow/) is: - -1. [Fork](https://github.com/pages-themes/cayman/fork) and clone the project -2. Configure and install the dependencies: `script/bootstrap` -3. Make sure the tests pass on your machine: `script/cibuild` -4. Create a new branch: `git checkout -b my-branch-name` -5. Make your change, add tests, and make sure the tests still pass -6. Push to your fork and [submit a pull request](https://github.com/pages-themes/cayman/compare) -7. Pat your self on the back and wait for your pull request to be reviewed and merged - -**Interesting in submitting your first Pull Request?** It's easy! You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) - -## Bootstrapping your local development environment - -`script/bootstrap` - -## Running tests - -`script/cibuild` - -## Code of conduct - -This project is governed by [the Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. - -## Additional Resources - -* [Contributing to Open Source on GitHub](https://guides.github.com/activities/contributing-to-open-source/) -* [Using Pull Requests](https://help.github.com/articles/using-pull-requests/) -* [GitHub Help](https://help.github.com) diff --git a/docs/SUPPORT.md b/docs/SUPPORT.md deleted file mode 100644 index 68a11de..0000000 --- a/docs/SUPPORT.md +++ /dev/null @@ -1,9 +0,0 @@ -## Where to get help - -If you think you've found a bug in The Cayman Theme, please [check the existing issues](https://github.com/pages-themes/cayman/issues), and if no one has reported the problem, [open a new issue](https://github.com/pages-themes/cayman/issues/new). - -If you have a general question about the theme, how to implement it, or how to customize it for your site you have two options: - -1. [Contact GitHub Support](https://github.com/contact?form%5Bsubject%5D=GitHub%20Pages%20theme%20pages-themes/cayman), or - -2. Ask your question of the Jekyll community on [talk.jekyllrb.com](https://talk.jekyllrb.com/) diff --git a/docs/ads.txt b/docs/ads.txt new file mode 100644 index 0000000..dd1f4b8 --- /dev/null +++ b/docs/ads.txt @@ -0,0 +1 @@ +google.com, pub-8127371937306964, DIRECT, f08c47fec0942fa0 \ No newline at end of file diff --git a/docs/core-properties.html b/docs/core-properties.html new file mode 100644 index 0000000..b5577ab --- /dev/null +++ b/docs/core-properties.html @@ -0,0 +1,343 @@ + + + + + + + +Untitled + + + + + + +
+
+
+ +
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameDefault ValueDescription

springdoc.api-docs.path

/v3/api-docs

String, For custom path of the OpenAPI documentation in Json format.

springdoc.api-docs.enabled

true

Boolean. To disable the springdoc-openapi endpoint (/v3/api-docs by default).

springdoc.packages-to-scan

*

List of Strings. The list of packages to scan (comma separated)

springdoc.paths-to-match

/*

List of Strings. The list of paths to match (comma separated)

springdoc.produces-to-match

/*

List of Strings. The list of produces mediaTypes to match (comma separated)

springdoc.headers-to-match

/*

List of Strings. The list of headers to match (comma separated)

springdoc.consumes-to-match

/*

List of Strings. The list of consumes mediaTypes to match (comma separated)

springdoc.paths-to-exclude

List of Strings. The list of paths to exclude (comma separated)

springdoc.packages-to-exclude

List of Strings. The list of packages to exclude (comma separated)

springdoc.default-consumes-media-type

application/json

String. The default consumes media type.

springdoc.default-produces-media-type

/

String. The default produces media type.

springdoc.cache.disabled

false

Boolean. To disable the springdoc-openapi cache of the calculated OpenAPI.

springdoc.show-actuator

false

Boolean. To display the actuator endpoints.

springdoc.auto-tag-classes

true

Boolean. To disable the springdoc-openapi automatic tags.

springdoc.model-and-view-allowed

false

Boolean. To allow RestControllers with ModelAndView return to appear in the OpenAPI description.

springdoc.override-with-generic-response

true

Boolean. When true, automatically adds @ControllerAdvice responses to all the generated responses.

springdoc.group-configs[0].group

String. The group name

springdoc.group-configs[0].display-name

String. The display name of the group.

springdoc.group-configs[0].packages-to-scan

*

List of Strings. The list of packages to scan for a group (comma separated)

springdoc.group-configs[0].paths-to-match

/*

List of Strings. The list of paths to match for a group (comma separated)

springdoc.group-configs[0].paths-to-exclude

``

List of Strings. The list of paths to exclude for a group (comma separated)

springdoc.group-configs[0].packages-to-exclude

List of Strings. The list of packages to exclude for a group (comma separated)

springdoc.group-configs[0].produces-to-match

/*

List of Strings. The list of produces mediaTypes to match (comma separated)

springdoc.group-configs[0].consumes-to-match

/*

List of Strings. The list of consumes mediaTypes to match (comma separated)

springdoc.group-configs[0].headers-to-match

/*

List of Strings. The list of headers to match (comma separated)

springdoc.webjars.prefix

/webjars

String. To change the webjars prefix that is visible the URL of swagger-ui for spring-webflux.

springdoc.api-docs.resolve-schema-properties

false

Boolean. To enable property resolver on @Schema (name, title and description).

springdoc.remove-broken-reference-definitions

true

Boolean. To disable removal of broken reference definitions.

springdoc.writer-with-default-pretty-printer

false

Boolean. To enable pretty print of the OpenApi specification.

springdoc.model-converters.deprecating-converter.enabled

true

Boolean. To disable deprecating model converter.

springdoc.model-converters.polymorphic-converter.enabled

true

Boolean. To disable polymorphic model converter.

springdoc.model-converters.pageable-converter.enabled

true

Boolean. To disable pageable model converter.

springdoc.model-converters.sort-converter.enabled

true

Boolean. To disable Sort converter.

springdoc.use-fqn

false

Boolean. To enable fully qualified names.

springdoc.show-login-endpoint

false

Boolean. To make spring security login-endpoint visible.

springdoc.pre-loading-locales

List of Strings. The list of locales to load OpenAPI on application startup (comma separated). If not specified, it will preload with the default Locale.

springdoc.writer-with-order-by-keys

false

Boolean. Enable a deterministic/alphabetical ordering.

springdoc.use-management-port

false

Boolean. To expose the swagger-ui on the actuator management port.

springdoc.disable-i18n

false

Boolean. To disable automatic translation using i18n.

springdoc.show-spring-cloud-functions

true

Boolean. To display the spring-cloud-function web endpoints.

springdoc.enable-groovy

true

Boolean. To enable Groovy support.

springdoc.enable-spring-security

true

Boolean. To enable spring-security support.

springdoc.enable-kotlin

true

Boolean. To enable Kotlin support.

springdoc.enable-hateoas

true

Boolean. To enable spring-hateoas support.

springdoc.enable-data-rest

true

Boolean. To enable spring-data-rest support.

springdoc.api-docs.version

openapi_3_1

String. To choose OpenAPI 3.0 or OpenAPI 3.1 (using the value OPENAPI_3_1).

springdoc.default-flat-param-object

false

Boolean. To default flatten parameter.

springdoc.default-support-form-data

false

Boolean. To default set parameters to form data when specifying api to accept form data.

springdoc.nullable-request-parameter-enabled

true

Boolean. To default Enable Support for nullable request parameters in Kotlin.

springdoc.show-oauth2-endpoints

false

Boolean. To make spring security oauth2-endpoint visible.

springdoc.api-docs.resolve-extensions-properties

false

Boolean. To enable support of spring property resolver for @ExtensionProperty.

springdoc.enable-default-api-docs

true

Boolean. To enable default OpenAPI endpoint /v3/api-docs.

springdoc.trim-kotlin-indent

false

Boolean. Adjust indentation when parsing the @Operation annotation in Kotlin.

springdoc.allowed-locales

List of Strings. The list of allowed locales for OpenAPI (comma separated, for example US,fr-CA).

springdoc.enable-extra-schemas

true

Boolean. To enable default support for extra Schemas, from java.time package like LocalTime, Duration, but also other Java classes like java.util.Locale or java.nio.charset.Charset

springdoc.explicit-object-schema

false

Boolean. Set explicit-object-schema to true to always include type: object in the schema, or to false to omit type: object.

springdoc.use-arbitrary-schemas

false

Boolean. When set to true, schemas without a defined type will be deserialized as an ArbitrarySchema (with no type), instead of an ObjectSchema with type: object.

+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/css/font-awesome.css b/docs/css/font-awesome.css new file mode 100755 index 0000000..ee906a8 --- /dev/null +++ b/docs/css/font-awesome.css @@ -0,0 +1,2337 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('../fonts/fontawesome-webfont.eot?v=4.7.0'); + src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/docs/css/site.css b/docs/css/site.css new file mode 100755 index 0000000..1e66082 --- /dev/null +++ b/docs/css/site.css @@ -0,0 +1,7 @@ +/* + +Source Available at https://github.com/spring-io/asciidoctor-spring-backend */ + + +:root{--html-font-size:1em;--pixel-to-rem:16 * 1rem;--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-banner-logo-offset:18px;--layout-banner-logo-height:50px;--layout-max-width:1400px;--layout-banner-height:80px;--layout-border-color:var(--color-accent-1);--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-embellishment-margin-width:250px;--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-width:24rem;--toc-display:block;--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-display:none;--toc-bar-height:0;--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)}@media screen and (max-width:1024px){:root{--toc-width:16rem;--asciidoctor-doc-embellishment-margin-width:140px}}@media screen and (max-width:800px){:root{--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}}html.dark-theme{--font-weight:300;--body-background-color:#1b1f23;--panel-background-color:#262a2d;--panel-group-background-color:#303741;--panel-border-color:#2c3135;--color-accent-1:#272c33;--color-accent-1-invert:#d8d3cc;--color-accent-2:#2d333a;--color-accent-3:#6db33f;--body-font-color:#bbbcbe;--body-font-light-color:#abacaf;--body-font-dark-color:#cecfd1;--link-font-color:#086dc3;--hover-link-font-color:#107ddd;--scrollbar-thumb-color:#5f5f5f;--mark-background-color:#2eca12;--selected-background-color:#8d8d8d;--layout-switchtheme-invert-filter:none;--layout-switchtheme-background-color:var(--selected-background-color);--asciidoctor-code-background:rgba(177,209,241,.15);--asciidoctor-code-data-lang-color:#6e6e6e;--asciidoctor-admonition-font-color:#f0f0f0;--asciidoctor-admonition-caution-background:#603668;--asciidoctor-admonition-important-background:#924040;--asciidoctor-admonition-note-background:#355463;--asciidoctor-admonition-tip-background:#4d6340;--asciidoctor-admonition-warning-background:#967745;--asciidoctor-footer-font-color:#5e5e5e;--highlight-background-color:var(--asciidoctor-pre-background);--highlight-font-color:#f6f8fa;--highlight-keyword-font-color:#ea4a5a;--highlight-comment-font-color:#959da5;--highlight-string-font-color:#79b8ff;--highlight-meta-font-color:#959da5;--highlight-constant-font-color:#79b8ff;--highlight-variable-font-color:#c8e1ff;--highlight-tag-font-color:#7bcc72;--highlight-tag-attribute-font-color:#b392f0;--highlight-type-font-color:#b392f0;--highlight-link-font-color:#1565c0;--highlight-addition-font-color:#7bcc72;--highlight-deletion-font-color:#f6f8fa;--highlight-regex-font-color:#79b8ff;--toc-back-to-index-filter:invert();--toc-bar-button-filter:invert();--codetools-button-filter:invert();--codetools-button-active-filter:none;--codetools-hover-background-color:var(--color-accent-1-invert);--codetools-border-color:hsla(0,0%,100%,.274);--codetools-divider-color:rgba(44,44,44,.274)}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{-webkit-text-size-adjust:none;-moz-text-size-adjust:none;text-size-adjust:none}html{font-size:var(--html-font-size);height:100%;min-width:340px;scroll-behavior:smooth}body{background-color:var(--body-background-color);color:var(--body-font-color);font-family:var(--font-family);font-weight:var(--font-weight);margin:0;overflow-wrap:anywhere;overscroll-behavior:none}a{text-decoration:none}a:hover{text-decoration:underline}a:active{background-color:none}code,kbd,pre{font-family:var(--monospace-font-family)}@supports (scrollbar-width:thin){body *{scrollbar-color:var(--scrollbar-thumb-color) transparent;scrollbar-width:thin}}table{word-wrap:normal;border-collapse:collapse}mark{background:var(--mark-background-color)}#banner-container{border-bottom:1px solid var(--layout-border-color);height:var(--layout-banner-height);overflow:hidden}#banner{background:no-repeat top var(--layout-banner-logo-offset) left var(--layout-banner-logo-offset) /auto var(--layout-banner-logo-height);background-image:url(../img/banner-logo.svg);height:100%}#doc{overflow:auto}.contained{margin:0 auto;max-width:var(--layout-max-width)}#switch-theme label,div#switch-theme{display:none}html.js div#switch-theme{display:block;float:right;margin:8px 6px 0 0}#switch-theme input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:no-repeat url(../img/octicons-16.svg#view-sun) 90% 50%/16px 16px,no-repeat url(../img/octicons-16.svg#view-moon) 10% 50%/16px 16px;background-color:var(--layout-switchtheme-background-color);height:22px;outline:none;position:relative;width:40px}#switch-theme input,#switch-theme input:before{border-radius:25px;filter:var(--layout-switchtheme-invert-filter)}#switch-theme input:before{background-color:var(--layout-switchtheme-button-color);content:"";height:18px;left:2px;position:absolute;top:2px;transition:transform .2s;width:18px}#switch-theme:hover input:before{background-color:var(--layout-switchtheme-button-hover-color)}#switch-theme input:checked:before{transform:translateX(18px)}.doc{color:var(--asciidoctor-font-color);-webkit-hyphens:none;hyphens:none;letter-spacing:-.0027777778rem;line-height:1.6;margin:0}.doc #content,.doc #footer{margin:0 2rem}.doc #header>:not(#toc){margin-left:2rem;margin-right:2rem}.doc #content{padding-bottom:4rem}#doc{background:no-repeat 100% 0/305px 147px;background-image:url(../img/doc-background.svg)}.doc #header{margin-right:var(--asciidoctor-doc-embellishment-margin-width)}.doc #header .details{background:var(--asciidoctor-details-background);color:var(--asciidoctor-details-font-color);font-size:.8em;font-weight:600;padding:1rem 1.5rem}.doc #header div.details{display:flex;flex-wrap:wrap}#header .details br{display:none}.doc #header .details span.author:not(:last-of-type):after{color:var(--asciidoctor-author-separator-color);content:"\2022";font-weight:400;margin:.4em}.doc #header .details span.last-author:after{display:none}.doc #header .details #revnumber{flex-basis:100%;font-weight:200;margin-top:.5rem;text-transform:capitalize}.doc #preamble+.sect1,.doc .sect1+.sect1{margin-top:2rem}.doc .sect1+.sect1{border-top:1px solid var(--asciidoctor-section-divider-color)}.doc h1{font-size:2.3em}.doc h2{font-size:2em}.doc h3{font-size:1.7em}.doc h4{font-size:1.6em}.doc h5{font-size:1.4em}.doc h6{font-size:1.3em}.doc h1,.doc h2,.doc h3,.doc h4,.doc h5,.doc h6{color:var(--asciidoctor-heading-font-color);font-weight:var(--asciidoctor-heading-font-weight);-webkit-hyphens:none;hyphens:none;line-height:1.3;margin:1.3rem 0 0;padding-top:1.8rem}.doc h1.sect0{background:var(--asciidoctor-abstract-background);font-size:1.8em;margin:1.5rem -1rem 0;padding:.5rem 1rem}.doc h1:first-child{margin:1.3rem 0}.doc h2:not(.discrete){margin-left:-1rem;margin-right:-1rem;padding:1.8rem 1rem .1rem}.doc h3:not(.discrete){font-weight:var(--asciidoctor-alt-heading-font-weight)}.doc h1 .anchor,.doc h2 .anchor,.doc h3 .anchor,.doc h4 .anchor,.doc h5 .anchor,.doc h6 .anchor{font-weight:400;margin-left:-2ex;padding-left:.5ex;position:absolute;text-decoration:none;visibility:hidden;width:2.25ex}.doc h1 .anchor:before,.doc h2 .anchor:before,.doc h3 .anchor:before,.doc h4 .anchor:before,.doc h5 .anchor:before,.doc h6 .anchor:before{content:"\0023"}.doc h1:hover .anchor,.doc h2:hover .anchor,.doc h3:hover .anchor,.doc h4:hover .anchor,.doc h5:hover .anchor,.doc h6:hover .anchor{visibility:visible}.doc dl,.doc p{margin:0}.doc a.bare{-webkit-hyphens:none;hyphens:none}.doc a{color:var(--asciidoctor-link-font-color)}.doc a:hover{color:var(--asciidoctor-hover-link-font-color)}.doc a.unresolved{color:var(--asciidoctor-unresolved-link-font-color)}.doc .admonitionblock code,.doc p code,.doc thead code{background:var(--asciidoctor-code-background);border-radius:.25em;color:var(--asciidoctor-code-font-color);font-size:.95em;padding:.125em .25em}.doc .admonitionblock a code,.doc p a code,.doc thead a code{color:var(--asciidoctor-code-link-font-color)}.doc code,.doc pre{-webkit-hyphens:none;hyphens:none}.doc pre{font-size:calc(14/var(--pixel-to-rem));line-height:1.3;margin:0}.doc .listingblock pre:not(.highlight),.doc .literalblock pre,.doc pre.highlight code{background:var(--asciidoctor-pre-background);border-radius:4px;box-shadow:inset 0 0 1.75px var(--asciidoctor-pre-border-color);display:block;overflow-x:auto;padding:.95rem}.doc pre.highlight code[data-lang]:before{color:var(--asciidoctor-code-data-lang-color);content:attr(data-lang);display:block;font-size:.65em;line-height:1;position:absolute;right:.3rem;text-transform:uppercase;top:.3rem}.doc pre.highlight{position:relative}.doc table pre.highlight code[data-lang]:before{display:none}.doc blockquote{margin:0}.doc .paragraph.lead>p{font-size:calc(18/var(--pixel-to-rem))}.doc .dlist,.doc .exampleblock,.doc .hdlist,.doc .imageblock,.doc .listingblock,.doc .literalblock,.doc .olist,.doc .paragraph,.doc .partintro,.doc .quoteblock,.doc .sidebarblock,.doc .ulist,.doc .verseblock,.doc details,.doc hr{margin:1rem 0 0}.doc table.tableblock{display:block;overflow-x:auto;width:100%}.doc table.tableblock td{min-width:6rem}.doc table.tableblock{font-size:calc(15/var(--pixel-to-rem));margin:1.5rem 0 0}.doc table.tableblock+*{margin-top:2rem}.doc td.tableblock>.content>:first-child{margin-top:0}.doc table.tableblock td,.doc table.tableblock th{padding:.5rem}.doc table.tableblock thead th{border-bottom:2.5px solid var(--asciidoctor-table-border-color)}.doc table.tableblock td,.doc table.tableblock>:not(thead) th{border-bottom:1px solid var(--asciidoctor-table-border-color);border-top:1px solid var(--asciidoctor-table-border-color)}.doc table.stripes-all>tbody>tr,.doc table.stripes-even>tbody>tr:nth-of-type(2n),.doc table.stripes-hover>tbody>tr:hover,.doc table.stripes-odd>tbody>tr:nth-of-type(odd){background:var(--asciidoctor-table-stripe-background)}.doc table.tableblock>tfoot{background:var(--asciidoctor-table-footer-background)}.doc .listingblock.wrap pre,.doc .tableblock code,.doc .tableblock pre{white-space:pre-wrap}.doc td:first-child .listingblock.wrap pre,.doc td:first-child .tableblock code,.doc td:first-child .tableblock pre{white-space:nowrap}.doc .admonitionblock{margin:2.5rem 0}.doc .admonitionblock p,.doc .admonitionblock td.content{font-size:calc(16/var(--pixel-to-rem))}.doc .admonitionblock td.content>.title+*,.doc .admonitionblock td.content>:not(.title):first-child{margin-top:0}.doc .admonitionblock pre{border:none;font-size:calc(14/var(--pixel-to-rem))}.doc .admonitionblock>table{position:relative;table-layout:fixed;width:100%}.doc .admonitionblock td.content{word-wrap:anywhere;background:var(--asciidoctor-admonition-background);padding:1rem 1rem .75rem;width:100%}.doc .admonitionblock td.icon{border-radius:.45rem;font-size:calc(16/var(--pixel-to-rem));left:0;line-height:1;padding:.25em .075em;position:absolute;top:0;transform:translate(-.5rem,-50%)}.doc .admonitionblock .icon i{align-items:center;background-position:.5em 0;background-repeat:no-repeat;display:inline-flex;filter:invert(100%);height:16px;padding-left:2em;vertical-align:initial;width:auto}.doc .admonitionblock .icon i:after{border-left:1px solid hsla(0,0%,100%,.3);color:var(--asciidoctor-admonition-font-color);content:attr(title);filter:invert(100%);font-style:normal;font-weight:var(--asciidoctor-admonition-label-font-weight);-webkit-hyphens:none;hyphens:none;margin:-.05em;padding:0 .5em;text-transform:capitalize}i.fa{background-size:16px 16px}i.fa.icon-caution{background-image:url(../img/octicons-16.svg#view-flame)}i.fa.icon-important{background-image:url(../img/octicons-16.svg#view-stop)}i.fa.icon-note{background-image:url(../img/octicons-16.svg#view-info)}i.fa.icon-tip{background-image:url(../img/octicons-16.svg#view-light-bulb)}i.fa.icon-warning{background-image:url(../img/octicons-16.svg#view-alert)}.doc .admonitionblock.caution td.icon{background:var(--asciidoctor-admonition-caution-background)}.doc .admonitionblock.important td.icon{background:var(--asciidoctor-admonition-important-background)}.doc .admonitionblock.note .icon{background:var(--asciidoctor-admonition-note-background)}.doc .admonitionblock.tip .icon{background:var(--asciidoctor-admonition-tip-background)}.doc .admonitionblock.warning .icon{background-color:var(--asciidoctor-admonition-warning-background)}.doc .imageblock{align-items:center;display:flex;flex-direction:column}.doc .image>img,.doc .imageblock img{display:inline-block;height:auto;max-width:100%;vertical-align:middle}.doc .image:not(.left):not(.right)>img{margin-top:-.2em}.doc #preamble .abstract blockquote{background:var(--asciidoctor-abstract-background);border-left:5px solid var(--asciidoctor-abstract-border-color);font-size:calc(16/var(--pixel-to-rem));padding:.75em 1em}.doc .quoteblock,.doc .verseblock{background:var(--asciidoctor-quote-background);border-left:5px solid var(--asciidoctor-quote-border-color)}.doc .quoteblock{padding:.25rem 2rem 1.25rem}.doc .quoteblock .attribution{color:var(--asciidoctor-quote-attribution-font-color);font-size:calc(15/var(--pixel-to-rem));margin-top:.75rem}.doc .quoteblock blockquote{margin-top:1rem}.doc .quoteblock .paragraph{font-style:italic}.doc .quoteblock cite{padding-left:1em}.doc .verseblock{font-size:1.15em;padding:1rem 2rem}.doc .verseblock pre{font-family:inherit;font-size:inherit}.doc ol,.doc ul{margin:0;padding:0 0 0 2rem}.doc ol.none,.doc ol.unnumbered,.doc ol.unstyled,.doc ul.checklist,.doc ul.no-bullet,.doc ul.none,.doc ul.unstyled{list-style-type:none}.doc ol.unnumbered,.doc ul.no-bullet{padding-left:1.25rem}.doc ol.unstyled,.doc ul.unstyled{padding-left:0}.doc ul.circle,.doc ul.disc,.doc ul.square{list-style-type:square}.doc ol.arabic{list-style-type:decimal}.doc ol.decimal{list-style-type:decimal-leading-zero}.doc ol.loweralpha{list-style-type:lower-alpha}.doc ol.upperalpha{list-style-type:upper-alpha}.doc ol.lowerroman{list-style-type:lower-roman}.doc ol.upperroman{list-style-type:upper-roman}.doc ol.lowergreek{list-style-type:lower-greek}.doc ul.checklist{padding-left:.5rem}.doc ul.checklist p>i.fa-check-square-o:first-child,.doc ul.checklist p>i.fa-square-o:first-child{display:inline-flex;justify-content:center;width:1.25rem}.doc ul.checklist i.fa-check-square-o:before{content:"\2713"}.doc ul.checklist i.fa-square-o:before{content:"\274f"}.doc .dlist .dlist,.doc .dlist .olist,.doc .dlist .ulist,.doc .olist .dlist,.doc .olist .olist,.doc .olist .ulist,.doc .ulist .dlist,.doc .ulist .olist,.doc .ulist .ulist{margin-top:.5rem}.doc .olist li,.doc .ulist li{margin-bottom:.3rem}.doc .admonitionblock .listingblock,.doc .olist .listingblock,.doc .ulist .listingblock{padding:0}.doc .admonitionblock .title,.doc .exampleblock .title,.doc .imageblock .title,.doc .listingblock .title,.doc .literalblock .title,.doc .openblock .title,.doc .tableblock caption{color:var(--asciidoctor-caption-font-color);font-size:calc(14/var(--pixel-to-rem));font-style:italic;font-weight:var(--asciidoctor-caption-font-weight);-webkit-hyphens:none;hyphens:none;letter-spacing:.01em;padding-bottom:.075rem;text-align:left}.doc .imageblock .title{margin-top:.5rem;padding-bottom:0}.doc .exampleblock>.content{background:var(--asciidoctor-example-background);border:1px solid var(--asciidoctor-example-border-color);border-radius:4px;padding:.75rem}.doc .exampleblock>.content>:first-child{margin-top:0}.doc .sidebarblock{background:var(--asciidoctor-sidebar-background);padding:2.2rem}.doc .sidebarblock>.content>.title{font-size:calc(23/var(--pixel-to-rem));font-weight:var(--asciidoctor-alt-heading-font-weight);line-height:1.3;margin-bottom:1.2rem}.doc .sidebarblock>.content>:not(.title):first-child{margin-top:0}.doc b.button{white-space:nowrap}.doc b.button:before{content:"[";padding-right:.25em}.doc b.button:after{content:"]";padding-left:.25em}.doc .menuseq,.doc .path{-webkit-hyphens:none;hyphens:none}.doc .menuseq i.caret:before{content:"\203a";font-size:1.1em;font-weight:var(--asciidoctor-body-font-weight-bold);line-height:.90909}.doc kbd{background:var(--asciidoctor-kbd-background);border:1px solid var(--asciidoctor-kbd-border-color);border-radius:.25em;box-shadow:0 1px 0 var(--asciidoctor-kbd-border-color),0 0 0 .1em var(--body-background) inset;display:inline-block;font-size:calc(12/var(--pixel-to-rem));padding:.25em .5em;vertical-align:text-bottom;white-space:nowrap}.doc .keyseq,.doc kbd{line-height:1}.doc .keyseq{font-size:calc(16/var(--pixel-to-rem))}.doc .keyseq kbd{margin:0 .125em}.doc .keyseq kbd:first-child{margin-left:0}.doc .keyseq kbd:last-child{margin-right:0}.doc i.fa{font-style:normal;-webkit-hyphens:none;hyphens:none}.doc .language-console .hljs-meta{-webkit-user-select:none;-moz-user-select:none;user-select:none}.doc .dlist dt{font-style:italic}.doc .dlist dd{margin:0 0 .25rem 1.5rem}.doc .dlist dd:last-of-type{margin-bottom:0}.doc td.hdlist1,.doc td.hdlist2{padding:.5rem 0 0;vertical-align:top}.doc tr:first-child>.hdlist1,.doc tr:first-child>.hdlist2{padding-top:0}.doc td.hdlist1{font-weight:var(--body-font-weight-bold);padding-right:.25rem}.doc td.hdlist2{padding-left:.25rem}.doc .colist{font-size:calc(16/var(--pixel-to-rem));margin:.25rem 0 -.25rem}.doc .colist>table>tbody>tr>:first-child,.doc .colist>table>tr>:first-child{padding:.25em .5rem 0;vertical-align:top}.doc .colist>table>tbody>tr>:last-child,.doc .colist>table>tr>:last-child{padding:.25rem 0}.doc .conum[data-value]{background:var(--asciidoctor-callout-background);border-radius:100%;color:var(--asciidoctor-callout-font-color);display:inline-block;font-family:var(--monospace-font-family);font-size:calc(12.5/var(--pixel-to-rem));font-style:normal;height:1.25em;letter-spacing:-.25ex;line-height:1.2;text-align:center;text-indent:-.25ex;width:1.25em}.doc .conum[data-value]:after{content:attr(data-value)}.doc .conum[data-value]+b{display:none}.doc hr{border:solid var(--asciidoctor-section-divider-color);border-width:2px 0 0;height:0}.doc :not(pre).nowrap{white-space:nowrap}.doc .nobreak{word-wrap:normal;-webkit-hyphens:none;hyphens:none}.doc .right{float:right}.doc .left{float:left}.doc .stretch{width:100%}.doc .underline{text-decoration:underline}.doc .line-through{text-decoration:line-through}.doc .halign-left{text-align:left}.doc .halign-right{text-align:right}.doc .halign-center{text-align:center}.doc .valign-top{vertical-align:top}.doc .valign-bottom{vertical-align:bottom}.doc .valign-middle{vertical-align:middle}#footer #footer-text{border-top:1px solid var(--asciidoctor-section-divider-color);color:var(--asciidoctor-footer-font-color);font-size:calc(14/var(--pixel-to-rem));padding:2rem 0}html.dark-theme #doc{background:no-repeat 100% 0/305px 147px;background-image:url(../img/doc-background-dark.svg)}@media screen and (max-width:1024px){#doc{background:no-repeat 100% 0/203px 95px;background-image:url(../img/doc-background.svg)}html.dark-theme #doc{background:no-repeat 100% 0/203px 95px;background-image:url(../img/doc-background-dark.svg)}}@media screen and (max-width:800px){#doc,html.dark-theme #doc{background:none}}.hljs{background:var(--highlight-background-color);color:var(--highlight-font-color);display:block;overflow-x:auto;padding:.5em}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:var(--highlight-keyword-font-color)}.hljs-comment,.hljs-quote{color:var(--highlight-comment-font-color)}.hljs-doctag,.hljs-string{color:var(--highlight-string-font-color)}.hljs-meta{color:var(--highlight-meta-font-color)}.hljs-built_in,.hljs-builtin-name,.hljs-literal,.hljs-number,.hljs-symbol{color:var(--highlight-constant-font-color)}.hljs-template-variable,.hljs-variable{color:var(--highlight-variable-font-color)}.hljs-attribute,.hljs-name,.hljs-tag{color:var(--highlight-tag-font-color)}.hljs-tag .hljs-attr{color:var(--highlight-tag-attribute-font-color)}.hljs-class .hljs-title,.hljs-type{color:var(--highlight-type-font-color)}.hljs-regexp{color:var(--highlight-regex-font-color)}.hljs-link{color:var(--highlight-link-font-color);text-decoration:underline}.hljs-addition{color:var(--highlight-addition-font-color)}.hljs-deletion{color:var(--highlight-deletion-font-color)}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.language-json .hljs-literal,.language-json .hljs-number{color:var(--highlight-variable-font-color)}.language-json .hljs-attr{color:var(--highlight-string-font-color)}.hidden{display:none}.doc .tabs{border-style:none;bottom:0;display:inline-block;font-size:calc(12/var(--pixel-to-rem));font-weight:700;margin-bottom:calc(2/var(--pixel-to-rem));margin-top:.5rem;position:relative}.doc .tab,.doc .tab:not(:first-child){border:1px solid var(--tabs-border-color)}.doc .tab{background-color:var(--tabs-background-color);border-radius:0;color:var(--tabs-font-color);cursor:pointer;display:inline-block;margin-bottom:calc(2/var(--pixel-to-rem));padding:.3rem .6rem;transition:background-color .2s}.doc .tab:hover{background-color:var(--tabs-hover-background);color:var(--tabs-hover-font-color);text-decoration:underline}.doc .tab.selected{background-color:var(--tabs-selected-background-color);border-color:var(--tabs-selected-background-color);color:var(--tabs-selected-font-color)}.doc .tab.selected:hover{color:var(--tabs-selected-font-color);text-decoration:none}.doc div.openblock.tabs-content>.content{background-color:var(--tabs-group-background-color);padding:1rem}body.toc-left #doc{border-left:1px solid var(--layout-border-color);margin-left:var(--toc-width);overflow:auto}#toc{border-right:1px solid var(--layout-border-color);display:var(--toc-display);font-size:.95rem;line-height:1.1;margin-left:calc(var(--toc-width)*-1);padding:1.7rem 1rem 0;position:absolute;top:var(--layout-banner-height);width:var(--toc-width)}#toctitle{display:none}#toc ol,#toc ul{padding:0}#toc ul ol,#toc ul ul{padding-left:.8rem}#toc li{display:block;list-style:none}#toc a{border-radius:4px;color:var(--toc-font-color);display:block;padding:.4rem .6rem;text-decoration:none}#toc a:hover{background-color:var(--toc-hover-background-color)}body.fixed-toc #toc{height:100%;overflow-x:hidden;position:fixed;top:0}#toc li.active>a{background-color:var(--toc-active-background-color);color:var(--toc-active-font-color)}#toc>ol ol,#toc>ul ul{display:none}#toc li.active>ol,#toc li.active>ul,#toc ol.expanded,#toc ul.expanded{display:block}#back-to-index{display:block;margin-bottom:.6rem}#back-to-index a{margin-bottom:.6rem;margin-top:-.9rem;padding-left:1.6rem}#back-to-index a:before{background:no-repeat 50%/16px 16px;background-image:url(../img/octicons-16.svg#view-chevron-left);content:"";display:block;filter:var(--toc-back-to-index-filter);left:1.4rem;min-height:16px;min-width:16px;position:absolute}#tocbar-container{background-color:var(--body-background-color);border-bottom:1px solid var(--panel-border-color);display:var(--toc-bar-display);height:var(--tocbar-height);width:100%;z-index:10000}#tocbar{height:100%;padding-left:6px;width:100%}body.fixed-toc #tocbar-container{position:fixed;top:0}button#toggle-toc{background:no-repeat 50%/16px 16px;background-image:url(../img/octicons-16.svg#view-three-bars);border:none;display:block;filter:var(--toc-bar-button-filter);height:var(--toc-bar-height);outline:none;padding:0;width:var(--toc-bar-height)}body.show-toc button#toggle-toc{background-image:url(../img/octicons-16.svg#view-x)}@media screen and (max-width:800px){body.fixed-toc #toc{top:var(--toc-bar-height)}#toc{background-color:var(--body-background-color);height:100%;left:0;top:calc(var(--layout-banner-height) + var(--toc-bar-height));width:100%;z-index:10000}body.show-toc #toc{display:block}}div.codetools{--button-width:28px;--button-height:24px;--arrow-size:5px;background:var(--codetools-background-color);border:1px solid var(--codetools-border-color);border-radius:2px;bottom:9px;display:flex;opacity:0;padding:0;position:absolute;right:8px;transition:opacity .15s ease-in-out}.doc pre.highlight:hover div.codetools{opacity:1}div.codetools button{background:no-repeat 50%/16px 16px;border:none;filter:var(--codetools-button-filter);height:var(--button-height);outline:none;padding:0;width:var(--button-width)}div.codetools button:not(:last-child){border-right:1px solid var(--codetools-divider-color)}div.codetools button:hover{background-color:var(--codetools-hover-background-color);transition:filter .3s}div.codetools button:active{filter:var(--codetools-button-active-filter);transition:filter none}div.codetools button span.label{display:none}div.codetools button.copy-button{background-image:url(../img/octicons-16.svg#view-clippy)}div.codetools button.unfold-button{background-image:url(../img/octicons-16.svg#view-unfold)}div.codetools button.fold-button{background-image:url(../img/octicons-16.svg#view-fold)}div.codetools span.copied{content:"";display:block;height:var(--button-height);opacity:0;position:relative;transition:opacity .5s;width:var(--button-width);z-index:1000000}div.codetools button:active span.copied{filter:invert();transition:filter none}div.codetools span.copied:before{border:var(--arrow-size) solid var(--codetools-popup-background-color);border-color:transparent transparent var(--codetools-popup-background-color) transparent;bottom:calc(var(--arrow-size)*-1);content:"";left:50%;margin-left:calc(var(--arrow-size)/-2);position:absolute}div.codetools span.copied:after{background-color:var(--codetools-popup-background-color);border-radius:3px;color:var(--codetools-popup-font-color);content:"Copied to clipboard!";font-weight:700;margin-right:calc(var(--button-width)*-1);padding:5px 8px;position:absolute;right:100%;top:calc(var(--button-height) + var(--arrow-size))}div.codetools button.clicked span.copied{opacity:1}span.fold-block{clear:left;float:left;overflow:hidden;padding-right:.75rem;position:relative}code.unfolded span.fold-block.hide-when-folded,code:not(.unfolded) span.fold-block.hide-when-unfolded{max-height:99999px;opacity:1}code.unfolded span.fold-block.hide-when-unfolded,code:not(.unfolded) span.fold-block.hide-when-folded{max-height:0;opacity:0}code.unfolding span.fold-block.hide-when-folded{max-height:600px;opacity:1}code.folding span.fold-block.hide-when-unfolded{max-height:400px;opacity:1}code.folding span.fold-block.hide-when-folded,code.unfolding span.fold-block.hide-when-unfolded{max-height:0;opacity:0}code.unfolding span.fold-block.hide-when-unfolded{transition:max-height .2s cubic-bezier(0,1,0,1),opacity .2s linear}code.folding span.fold-block.hide-when-unfolded,code.unfolding span.fold-block.hide-when-folded{transition:max-height .2s cubic-bezier(1,0,1,0),opacity .2s linear}code.folding span.fold-block.hide-when-folded{transition:max-height .2s cubic-bezier(0,1,0,1),opacity .2s linear} +/*# sourceMappingURL=site.css.map */ diff --git a/docs/css/site.css.map b/docs/css/site.css.map new file mode 100755 index 0000000..da9ab69 --- /dev/null +++ b/docs/css/site.css.map @@ -0,0 +1 @@ +{"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/docs/demos.html b/docs/demos.html new file mode 100644 index 0000000..ecfb903 --- /dev/null +++ b/docs/demos.html @@ -0,0 +1,98 @@ + + + + + + + +Springdoc-openapi Demos + + + + + + +
+
+
+ + + +
+
+
+ + \ No newline at end of file diff --git a/docs/faq.html b/docs/faq.html new file mode 100644 index 0000000..ae663fc --- /dev/null +++ b/docs/faq.html @@ -0,0 +1,2135 @@ + + + + + + + +F.A.Q + + + + + + +
+
+
+ +
+
+

F.A.Q

+
+
+

How can I define multiple OpenAPI definitions in one Spring Boot project?

+
+

You can define your own groups of API based on the combination of: API paths and packages to scan. Each group should have a unique groupName. +The OpenAPI description of this group, will be available by default on:

+
+
+
    +
  • +

    http://server:port/context-path/v3/api-docs/groupName

    +
  • +
+
+
+

To enable the support of multiple OpenAPI definitions, a bean of type GroupedOpenApi needs to be defined.

+
+
+

For the following Group definition(based on package path), the OpenAPI description URL will be : /v3/api-docs/stores

+
+
+
+
@Bean
+public GroupedOpenApi storeOpenApi() {
+   String paths[] = {"/store/**"};
+   return GroupedOpenApi.builder().group("stores").pathsToMatch(paths)
+         .build();
+}
+
+
+
+
+

For the following Group definition (based on package name), the OpenAPI description URL will be: /v3/api-docs/users

+
+
+
+
@Bean
+public GroupedOpenApi userOpenApi() {
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"};
+   return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan)
+         .build();
+}
+
+
+
+
+

For the following Group definition(based on path), the OpenAPI description URL will be: /v3/api-docs/pets

+
+
+
+
@Bean
+public GroupedOpenApi petOpenApi() {
+   String paths[] = {"/pet/**"};
+   return GroupedOpenApi.builder().group("pets").pathsToMatch(paths)
+         .build();
+}
+
+
+
+
+

For the following Group definition (based on package name and path), the OpenAPI description URL will be: /v3/api-docs/groups

+
+
+
+
@Bean
+public GroupedOpenApi groupOpenApi() {
+   String paths[] = {"/v1/**"};
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"};
+   return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
+         .build();
+}
+
+
+
+
+

For more details about the usage, you can have a look at the following sample Test:

+
+ +
+
+

How can I configure Swagger UI?

+
+
    +
  • +

    The support of the swagger official properties is available on springdoc-openapi. See Official documentation.

    +
  • +
  • +

    You can use the same swagger properties in the documentation as Spring Boot properties.

    +
  • +
+
+
+ + + + + +
+ + +All these properties should be declared with the following prefix: springdoc.swagger-ui +
+
+
+
+

How can I filter the resources documented in the output specification by the provided group?

+
+
    +
  • +

    You can use the standard swagger-ui property filter.

    +
  • +
+
+
+
+
springdoc.swagger-ui.filter=group-a
+
+
+
+
+

How can I disable/enable Swagger UI generation based on env variable?

+
+
    +
  • +

    This property helps you disable only the UI.

    +
  • +
+
+
+
+
springdoc.swagger-ui.enabled=false
+
+
+
+
+

How can I control the default expansion setting for the operations and tags, in the Swagger UI ,

+
+
    +
  • +

    You can set this property in your application.yml like so for example:

    +
  • +
+
+
+
+
springdoc.swagger-ui.doc-expansion= none
+
+
+
+
+

How can I change the layout of the swagger-ui?

+
+
    +
  • +

    For layout options, you can use swagger-ui configuration options. For example:

    +
  • +
+
+
+
+
springdoc.swagger-ui.layout=BaseLayout
+
+
+
+
+

How can I sort endpoints alphabetically?

+
+
    +
  • +

    You can use the following springdoc-openapi properties:

    +
  • +
+
+
+
+
#For sorting endpoints alphabetically
+springdoc.swagger-ui.operationsSorter=alpha
+#For sorting tags alphabetically
+springdoc.swagger-ui.tagsSorter=alpha
+
+
+
+
+

How can I disable the try it out button?

+
+
    +
  • +

    You have to set the following property:

    +
  • +
+
+
+
+
springdoc.swagger-ui.supportedSubmitMethods=get, put, post, delete, options, head, patch, trace
+
+
+
+
+

How can I add Reusable Enums ?

+
+
    +
  • +

    You should add @Schema(enumAsRef = true) on your enum.

    +
  • +
+
+
+
+

How can i apply enumAsRef = true to all enums ?

+
+
    +
  • +

    Declare the following property:

    +
  • +
+
+
+
+
static {
+    io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true;
+}
+
+
+
+
+

How can I explicitly set which paths to filter?

+
+
    +
  • +

    You can set list of paths to include using the following property:

    +
  • +
+
+
+
+
springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
+

How can I explicitly set which packages to scan?

+
+
    +
  • +

    You can set list of packages to include using the following property:

    +
  • +
+
+
+
+
springdoc.packagesToScan=package1, package2
+
+
+
+
+

How can I set Swagger properties programmatically?

+
+

These can be set by creating a swaggerUiConfig bean as follows:

+
+
+
+
@Bean
+@Primary
+fun swaggerUiConfig(config: SwaggerUiConfigProperties): SwaggerUiConfigProperties {
+    config.showCommonExtensions = true
+    config.queryConfigEnabled = true
+    return config
+}
+
+
+
+
+
+

How can I ignore some field of model ?

+
+
    +
  • +

    You can use the following annotation on the top of the field that you want to hide:

    +
  • +
  • +

    @Schema(hidden = true)

    +
  • +
+
+
+
+

How can I ignore @AuthenticationPrincipal parameter from spring-security ?

+
+
    +
  • +

    A solution workaround would be to use: @Parameter(hidden = true)

    +
  • +
  • +

    The projects that use spring-boot-starter-security or spring-security-oauth2-authorization-server should use:

    +
    +
      +
    • +

      springdoc-openapi-starter-webmvc-api if they depend on spring-boot-starter-web and they only need the access to the OpenAPI endpoints.

      +
    • +
    • +

      OR springdoc-openapi-starter-webmvc-ui, if they depend on spring-boot-starter-web and they also need the access to the swagger-ui.

      +
    • +
    • +

      OR springdoc-openapi-starter-webflux-api if they depend on spring-boot-starter-webflux and they only the access to the OpenAPI endpoints.

      +
    • +
    • +

      OR springdoc-openapi-starter-webflux-ui, if they depend on spring-boot-starter-webflux and they also need the access to the swagger-ui.

      +
    • +
    +
    +
  • +
+
+
+
+

Is there a Gradle plugin available?

+
+
    +
  • +

    Yes. More details are available, in the gradle plugin section.

    +
  • +
+
+
+
+

How can I hide a parameter from the documentation ?

+
+
    +
  • +

    You can use @Parameter(hidden = true)

    +
  • +
+
+
+
+

Is @Parameters annotation supported ?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

Does springdoc-openapi support Jersey?

+
+ +
+
+
+

Can springdoc-openapi generate API only for @RestController?

+
+
    +
  • +

    @RestController is equivalent to @Controller + @RequestMapping on the type level.

    +
  • +
  • +

    For some legacy apps, we are constrained to still support both.

    +
  • +
  • +

    If you need to hide the @Controller on the type level, in this case, you can use: @Hidden on controller level.

    +
  • +
  • +

    Please note this annotation can be also used to hide some methods from the generated documentation.

    +
  • +
+
+
+
+

Are the following validation annotations supported : @NotEmpty @NotBlank @PositiveOrZero @NegativeOrZero?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

How can I map Pageable (spring-data-commons) object to correct URL-Parameter in Swagger UI?

+
+

The support for Pageable of spring-data-commons is available out-of-the box since springdoc-openapi v1.6.0. +For this, you have to combine @ParameterObject annotation with the Pageable type.

+
+
+

Before springdoc-openapi v1.6.0:

+
+
+
    +
  • +

    You can use as well @ParameterObject instead of @PageableAsQueryParam for HTTP GET methods.

    +
  • +
+
+
+
+
static {
+    getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
+            .replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
+}
+
+
+
+
+
    +
  • +

    Another solution, is to configure Pageable manually:

    +
    +
      +
    • +

      you will have to declare the explicit mapping of Pageable fields as Query Params and add the @Parameter(hidden = true) Pageable pageable on your pageable parameter.

      +
    • +
    • +

      You should also, declare the annotation @PageableAsQueryParam provided by springdoc-openapi on the method level, or declare your own if need to define your custom description, defaultValue, …​

      +
    • +
    +
    +
  • +
+
+
+

If you want to disable the support of spring Pageable Type, you can use:

+
+
+
+
springdoc.model-converters.pageable-converter.enabled=false
+
+
+
+ + + + + +
+ + +The property springdoc.model-converters.pageable-converter.enabled is only available since v1.5.11+ +
+
+
+
+

How can I generate enums in the generated description?

+
+
    +
  • +

    You could add a property allowableValues, to @Parameter. For example:

    +
  • +
+
+
+
+
@GetMapping("/example")
+public Object example(@Parameter(name ="json", schema = @Schema(description = "var 1",type = "string", allowableValues = {"1", "2"}))
+String json) {
+   return null;
+}
+
+
+
+
+
    +
  • +

    or you could override toString on your enum:

    +
  • +
+
+
+
+
@Override
+@JsonValue
+public String toString() {
+   return String.valueOf(action);
+}
+
+
+
+
+
+

How can I deploy springdoc-openapi-starter-webmvc-ui behind a reverse proxy?

+
+
    +
  • +

    If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…​) might change along the way. Your application may be running on 10.10.10.10:8080, but HTTP clients should only see example.org.

    +
  • +
  • +

    RFC7239 "Forwarded Headers" defines the Forwarded HTTP header; proxies can use this header to provide information about the original request. You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages. There are also non-standard headers, like X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, and X-Forwarded-Prefix.

    +
  • +
  • +

    If the proxy adds the commonly used X-Forwarded-For and X-Forwarded-Proto headers, setting server.forward-headers-strategy to NATIVE is enough to support those. With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior.

    +
  • +
  • +

    You need to make sure the following header is set in your reverse proxy configuration: X-Forwarded-Prefix

    +
  • +
  • +

    For example, using Apache 2, configuration:

    +
  • +
+
+
+
+
RequestHeader set X-Forwarded-Prefix "/custom-path"
+
+
+
+
    +
  • +

    Then, in your Spring Boot application make sure your application handles this header: X-Forwarded-For. There are two ways to achieve this:

    +
  • +
+
+
+
+
server.use-forward-headers=true
+
+
+
+
    +
  • +

    If this is not enough, Spring Framework provides a ForwardedHeaderFilter. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK.

    +
  • +
  • +

    Since Spring Boot 2.2, this is the new property to handle reverse proxy headers:

    +
  • +
+
+
+
+
server.forward-headers-strategy=framework
+
+
+
+
    +
  • +

    And you can add the following bean to your application:

    +
  • +
+
+
+
+
@Bean
+ForwardedHeaderFilter forwardedHeaderFilter() {
+   return new ForwardedHeaderFilter();
+}
+
+
+
+
+
    +
  • +

    If you need to manually adjust the URL displayed in the Swagger UI, implement the ServerBaseUrlCustomizer interface. This might be necessary to remove the port number, for example.

    +
  • +
+
+
+
+
@Bean
+public class CustomServerBaseUrlCustomizer implements ServerBaseUrlCustomizer {
+    @Override
+    public String customize(String serverBaseUrl) {
+        try {
+            URL url = new URL(serverBaseUrl);
+            if (url.getHost().contains(".com")) {
+                serverBaseUrl = new URL(url.getProtocol(),url.getHost(),url.getFile()).toString();
+            }
+        } catch (MalformedURLException ex) {
+            // nothing we can do
+        }
+
+        return serverBaseUrl;
+    }
+}
+
+
+
+
+
+

Is @JsonView annotations in Spring MVC APIs supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

Adding springdoc-openapi-starter-webmvc-ui dependency breaks my public/index.html welcome page

+
+
    +
  • +

    If you already have static content on your root, and you don’t want it to be overridden by springdoc-openapi-starter-webmvc-ui configuration, you can just define a custom configuration of the swagger-ui, in order not to override the configuration of your files from in your context-root:

    +
  • +
  • +

    For example use:

    +
  • +
+
+
+
+
springdoc.swagger-ui.path= /swagger-ui/api-docs.html
+
+
+
+
+

How can I test the Swagger UI?

+ +
+
+

How can I customise the OpenAPI object ?

+
+ +
+
+
+
@Bean
+public OpenApiCustomizer consumerTypeHeaderOpenAPICustomizer() {
+return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
+    .forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myConsumerTypeHeader")));
+}
+
+
+
+
+ + + + + +
+ + +This bean OpenApiCustomizer will be applied to the Default OpenAPI only. +
+
+
+

If you need the OpenApiCustomizer to applied to GroupedOpenApi as well, then use GlobalOpenApiCustomizer instead.

+
+
+
+

How can I return an empty content as response?

+
+
    +
  • +

    It is be possible to handle as return an empty content as response using, one of the following syntaxes:

    +
  • +
  • +

    content = @Content

    +
  • +
  • +

    content = @Content(schema = @Schema(hidden = true))

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
@Operation(summary = "Get thing", responses = {
+      @ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
+      @ApiResponse(responseCode = "404", description = "Not found", content = @Content),
+      @ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) })
+@RequestMapping(path = "/testme", method = RequestMethod.GET)
+ResponseEntity<String> testme() {
+   return ResponseEntity.ok("Hello");
+}
+
+
+
+
+
+

How are endpoints with multiple consuming media types supported?

+
+
    +
  • +

    An overloaded method on the same class, with the same HTTP Method and path, will have as a result, only one OpenAPI Operation generated.

    +
  • +
  • +

    In addition, it’s recommended to have the @Operation in the level of one of the overloaded methods. Otherwise it might be overridden if it’s declared many times within the same overloaded method.

    +
  • +
+
+
+
+

How can I get yaml and json (OpenAPI) in compile time?

+
+ +
+
+
+

What are the ignored types in the documentation?

+
+ +
+
+
+

How can i disable ignored types:

+
+

If you don’t want to ignore the types Principal, Locale, HttpServletRequest, and others,:

+
+
+
+
SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class)
+
+
+
+
+
+

How do I add authorization header in requests?

+
+
    +
  • +

    You should add the @SecurityRequirement tags to your protected APIs.

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
@Operation(security = { @SecurityRequirement(name = "bearer-key") })
+
+
+
+
    +
  • +

    And the security definition sample:

    +
  • +
+
+
+
+
@Bean
+ public OpenAPI customOpenAPI() {
+   return new OpenAPI()
+          .components(new Components()
+          .addSecuritySchemes("bearer-key",
+          new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
+}
+
+
+
+
+
+

Differentiation to Springfox project

+
+
    +
  • +

    OAS 3 was released in July 2017, and there was no release of springfox to support OAS 3. +springfox covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately.

    +
  • +
  • +

    We decided to move forward and share the library that we already used on our internal projects, with the community.

    +
  • +
  • +

    The biggest difference with springfox, is that we integrate new features not covered by springfox:

    +
  • +
  • +

    The integration between Spring Boot and OpenAPI 3 standard.

    +
  • +
  • +

    We rely on on swagger-annotations and swagger-ui only official libraries.

    +
  • +
  • +

    We support new features on Spring 5, like spring-webflux with annotated and functional style.

    +
  • +
  • +

    We do our best to answer all the questions and address all issues or enhancement requests

    +
  • +
+
+
+
+

How do I migrate to OpenAPI 3 with springdoc-openapi

+
+
    +
  • +

    There is no relation between springdoc-openapi and springfox.If you want to migrate to OpenAPI 3:

    +
  • +
  • +

    Remove all the dependencies and the related code to springfox

    +
  • +
  • +

    Add springdoc-openapi-starter-webmvc-ui dependency

    +
  • +
  • +

    If you don’t want to serve the UI from your root path or there is a conflict with an existing configuration, you can just change the following property:

    +
  • +
+
+
+
+
springdoc.swagger-ui.path=/you-path/swagger-ui.html
+
+
+
+
+

How can I set a global header?

+
+
    +
  • +

    You may have global parameters with Standard OpenAPI description.

    +
  • +
  • +

    If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.

    +
  • +
  • +

    You can define common parameters under parameters in the global components section and reference them elsewhere via $ref. You can also define global header parameters.

    +
  • +
  • +

    For this, you can override to OpenAPI Bean, and set the global headers or parameters definition on the components level.

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+ return new OpenAPI()
+        .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
+        .addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
+        .info(new Info()
+        .title("Petstore API")
+        .version(appVersion)
+        .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
+        .termsOfService("http://swagger.io/terms/")
+        .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
+

Are Callbacks supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

How can I define SecurityScheme ?

+
+
    +
  • +

    You can use: @SecurityScheme annotation.

    +
  • +
  • +

    Or you can define it programmatically, by overriding OpenAPI Bean:

    +
  • +
+
+
+
+
 @Bean
+ public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+  return new OpenAPI()
+   .components(new Components().addSecuritySchemes("basicScheme",
+   new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+   info(new Info().title("SpringShop API").version(appVersion)
+   .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+ }
+
+
+
+
+
+

How can I hide an operation or a controller from documentation ?

+
+
    +
  • +

    You can use @io.swagger.v3.oas.annotations.Hidden annotation at @RestController, @RestControllerAdvice and method level

    +
  • +
  • +

    The @Hidden annotation on exception handler methods, is considered when building generic (error) responses from @ControllerAdvice exception handlers.

    +
  • +
  • +

    Or use: @Operation(hidden = true)

    +
  • +
+
+
+
+

How to configure global security schemes?

+
+
    +
  • +

    For global SecurityScheme, you can add it inside your own OpenAPI definition:

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI().components(new Components()
+    .addSecuritySchemes("basicScheme", new SecurityScheme()
+    .type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API")
+    .version("100")).addTagsItem(new Tag().name("mytag"));
+}
+
+
+
+
+
+

Can I use spring property with swagger annotations?

+
+
    +
  • +

    The support of spring property resolver for @Info: title * description * version * termsOfService

    +
  • +
  • +

    The support of spring property resolver for @Info.license: name * url

    +
  • +
  • +

    The support of spring property resolver for @Info.contact: name * email * url

    +
  • +
  • +

    The support of spring property resolver for @Operation: description * summary

    +
  • +
  • +

    The support of spring property resolver for @Parameter: description * name

    +
  • +
  • +

    The support of spring property resolver for @ApiResponse: description

    +
  • +
  • +

    Its also possible to declare security URLs for @OAuthFlow: openIdConnectUrl * authorizationUrl * refreshUrl * tokenUrl

    +
  • +
  • +

    The support of spring property resolver for @Schema: name * title * description , by setting springdoc.api-docs.resolve-schema-properties to true

    +
  • +
  • +

    The support of spring property resolver for @ExtensionProperty by setting springdoc.api-docs.resolve-extensions-properties to true

    +
  • +
+
+
+
+

How is server URL generated ?

+
+
    +
  • +

    Generating automatically server URL may be useful, if the documentation is not present.

    +
  • +
  • +

    If the server annotations are present, they will be used instead.

    +
  • +
+
+
+
+

How can I disable springdoc-openapi cache?

+
+
    +
  • +

    By default, the OpenAPI description is calculated once, and then cached.

    +
  • +
  • +

    Sometimes the same swagger-ui is served behind internal and external proxies. some users want the server URL, to be computed on each http request.

    +
  • +
  • +

    In order to disable springdoc cache, you will have to set the following property:

    +
  • +
+
+
+
+
springdoc.cache.disabled= true
+
+
+
+
+

How can I expose the mvc api-docs endpoints without using the swagger-ui?

+
+
    +
  • +

    You should use the springdoc-openapi-core dependency only:

    +
  • +
+
+
+
+
<dependency>
+  <groupId>org.springdoc</groupId>
+  <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
+  <version>latest.version</version>
+</dependency>
+
+
+
+
+

How can I disable springdoc-openapi endpoints ?

+
+
    +
  • +

    Use the following property:

    +
  • +
+
+
+
+
springdoc.api-docs.enabled=false
+
+
+
+
+

How can I hide Schema of the the response ?

+
+
    +
  • +

    To hide the response element, using @Schema annotation, as follows, at operation level:

    +
  • +
+
+
+
+
@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))))
+
+
+
+
    +
  • +

    Or directly at @ApiResponses level:

    +
  • +
+
+
+
+
@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) })
+OR
+@ApiResponse(responseCode = "404", description = "Not found", content = @Content)
+
+
+
+
+

What is the URL of the swagger-ui, when I set a different context-path?

+
+
    +
  • +

    If you use different context-path:

    +
  • +
+
+
+
+
server.servlet.context-path= /foo
+
+
+
+
    +
  • +

    The swagger-ui will be available on the following URL:

    +
    +
      +
    • +

      http://server:port/foo/swagger-ui.html

      +
    • +
    +
    +
  • +
+
+
+
+

Can I customize OpenAPI object programmatically?

+
+
    +
  • +

    You can Define your own OpenAPI Bean: If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+   return new OpenAPI()
+    .components(new Components().addSecuritySchemes("basicScheme",
+            new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+    .info(new Info().title("SpringShop API").version(appVersion)
+            .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
    +
  • +

    If you need the definitions to appear within a specific group, and respect the conditions specified on the GroupedOpenApi, you can add OpenApiCustomizer to your GroupedOpenApi definition.

    +
  • +
+
+
+
+
GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomizer(customerGlobalHeaderOpenApiCustomizer())
+                .build()
+
+@Bean
+public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() {
+   return openApi -> openApi.path("/foo",
+   new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses()
+   .addApiResponse("default",new ApiResponse().description("")
+   .content(new Content().addMediaType("fatz", new MediaType()))))));
+}
+
+
+
+
+
+

Where can I find the source code of the demo applications?

+
+ +
+
+
+

Does this library supports annotations from interfaces?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

What is the list of the excluded parameter types?

+ +
+
+

Is file upload supported ?

+
+
    +
  • +

    The library supports the main file types: MultipartFile, @RequestPart, FilePart

    +
  • +
  • +

    You can upload a file as follows:

    +
  • +
+
+
+
+
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Encoding;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+
+@PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+public ResponseEntity<?> upload(@Parameter(description = "file") final MultipartFile file) {
+    return null;
+}
+
+@PostMapping(value = "/uploadFileWithQuery", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+public ResponseEntity<?> uploadFileWithQuery(@Parameter(description = "file") @RequestPart("file") final MultipartFile file,
+        @Parameter(description = "An extra query parameter") @RequestParam String name) {
+    return null;
+}
+
+@PostMapping(value = "/uploadFileWithJson", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {
+        MediaType.APPLICATION_JSON_VALUE})
+public ResponseEntity<?> uploadFileWithJson(
+        @RequestBody(content = @Content(encoding = @Encoding(name = "jsonRequest", contentType = MediaType.APPLICATION_JSON_VALUE)))
+        @Parameter(description = "An extra JSON payload sent with file") @RequestPart("jsonRequest") final JsonRequest jsonRequest,
+        @RequestPart("file") final MultipartFile file) {
+    return null;
+}
+
+
+
+
+
+

Can I use @Parameter inside @Operation annotation?

+
+
    +
  • +

    Yes, it’s supported

    +
  • +
+
+
+
+

Why my parameter is marked as required?

+
+
    +
  • +

    Any @GetMapping parameters is marked as required, even if @RequestParam is missing.

    +
  • +
  • +

    You can add @Parameter(required=false) annotation if you need different behaviour.

    +
  • +
  • +

    Query parameters with defaultValue specified are marked as required.

    +
  • +
+
+
+
+

How are overloaded methods with the same endpoints, but with different parameters

+
+
    +
  • +

    springdoc-openapi renders these methods as a single endpoint. It detects the overloaded endpoints, and generates parameters.schema.oneOf.

    +
  • +
+
+
+
+

What is a proper way to set up Swagger UI to use provided spec.yml?

+
+
    +
  • +

    With this property, all the springdoc-openapi auto-configuration beans are disabled:

    +
  • +
+
+
+
+
springdoc.api-docs.enabled=false
+
+
+
+
    +
  • +

    Then enable the minimal Beans configuration, by adding this Bean:

    +
  • +
+
+
+
+
@Bean
+SpringDocConfiguration springDocConfiguration(){
+   return new SpringDocConfiguration();
+}
+
+@Bean
+SpringDocConfigProperties springDocConfigProperties() {
+   return new SpringDocConfigProperties();
+}
+
+@Bean
+ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){
+    return new ObjectMapperProvider(springDocConfigProperties);
+}
+
+
+
+
+
    +
  • +

    Then configure, the path of your custom UI yaml file.

    +
  • +
+
+
+
+
springdoc.swagger-ui.url=/api-docs.yaml
+
+
+
+
+

Is there a way to send authorization header through the @Parameter tag?

+
+ +
+
+
+

My Rest Controller using @Controller annotation is ignored?

+
+
    +
  • +

    This is the default behaviour if your @Controller doesn’t have annotation @ResponseBody

    +
  • +
  • +

    You can change your controllers to @RestControllers. Or add @ResponseBody + @Controller.

    +
  • +
  • +

    If its not possible, you can configure springdoc to scan you additional controller using SpringDocUtils. For example:

    +
  • +
+
+
+
+
static {
+   SpringDocUtils.getConfig().addRestControllers(HelloController.class);
+}
+
+
+
+
+
+

How can I define groups using application.yml?

+
+
    +
  • +

    You can load groups dynamically using spring-boot configuration files.

    +
  • +
  • +

    Note that, for this usage, you don’t have to declare the GroupedOpenApi Bean.

    +
  • +
  • +

    You need to declare the following properties, under the prefix springdoc.group-configs.

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
springdoc.group-configs[0].group=users
+springdoc.group-configs[0].paths-to-match=/user/**
+springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api
+
+
+
+ +
+
+
+

How can I extract fields from parameter object ?

+
+
    +
  • +

    You can use springdoc annotation @ParameterObject.

    +
  • +
  • +

    Request parameter annotated with @ParameterObject will help adding each field of the parameter as a separate request parameter.

    +
  • +
  • +

    This is compatible with Spring MVC request parameters mapping to POJO object.

    +
  • +
  • +

    This annotation does not support nested parameter objects.

    +
  • +
  • +

    POJO object must contain getters for fields with mandatory prefix get. Otherwise, the swagger documentation will not show the fields of the annotated entity.

    +
  • +
+
+
+
+

How can I use the last springdoc-openapi SNAPSHOT ?

+
+
    +
  • +

    For testing purposes only, you can test temporarily using the last springdoc-openapi SNAPSHOT

    +
  • +
  • +

    To achieve that, configure your pom.xml file with the following <repositories> section:

    +
  • +
+
+
+
+
    <repositories>
+      <repository>
+        <name>Central Portal Snapshots</name>
+        <id>central-portal-snapshots</id>
+        <url>https://central.sonatype.com/repository/maven-snapshots/</url>
+        <releases>
+          <enabled>false</enabled>
+        </releases>
+        <snapshots>
+          <enabled>true</enabled>
+        </snapshots>
+      </repository>
+    </repositories>
+
+
+
+
+

How can I use enable springdoc-openapi MonetaryAmount support ?

+
+
    +
  • +

    If an application wants to enable the springdoc-openapi support, it declares:

    +
  • +
+
+
+
+
SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
+
+
+
+
+
    +
  • +

    Another solution, without using springdoc-openapi MonetaryAmount, would be:

    +
  • +
+
+
+
+
SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema()
+            .addProperties("amount", new NumberSchema()).example(99.96)
+            .addProperties("currency", new StringSchema().example("USD")));
+
+
+
+
+
+

How can i aggregate external endpoints (exposing OPENAPI 3 spec) inside one single application?

+
+

The properties springdoc.swagger-ui.urls.*, are suitable to configure external (/v3/api-docs url). +For example if you want to agreagte all the endpoints of other services, inside one single application. +IMPORTANT: Don’t forget that CORS needs to be enabled as well.

+
+
+
+

How can use custom json/yml file instead of generated one ?

+
+

If your file open-api.json, contains the OpenAPI documentation in OpenAPI 3 format. +Then simply declare: The file name can be anything you want, from the moment your declaration is consistent yaml or json OpenAPI Spec.

+
+
+
+
   springdoc.swagger-ui.url=/open-api.json
+
+
+
+

Then the file open-api.json, should be located in: src/main/resources/static +No additional configuration is needed.

+
+
+
+

How can i enable CSRF support?

+
+

If you are using standard headers.( For example using spring-security headers) +If the CSRF Token is required, swagger-ui automatically sends the new XSRF-TOKEN during each HTTP REQUEST.

+
+
+

If your XSRF-TOKEN isn’t standards-based, you can use a requestInterceptor to manually capture and attach the latest xsrf token to requests programmatically via spring resource transformer:

+
+ +
+

Starting from release v1.4.4 of springdoc-openapi, a new property is added to enable CSRF support, while using standard header names:

+
+
+
+
springdoc.swagger-ui.csrf.enabled=true
+
+
+
+
+

How can i disable the default swagger petstore URL?

+
+

You can use the following property:

+
+
+
+
springdoc.swagger-ui.disable-swagger-default-url=true
+
+
+
+
+

Is @PageableDefault supported, to enhance the OpenAPI 3 docuementation?

+
+

Yes, you can use it in conjunction with @ParameterObject annotation. +Also, the spring-boot spring.data.web. and spring.data.rest.default. properties are supported since v1.4.5

+
+
+
+

How can i make spring security login-endpoint visible ?

+
+

You can use the following property:

+
+
+
+
springdoc.show-login-endpoint=true
+
+
+
+
+

How can i show schema definitions even the schema is not referenced?

+
+

You can use the following property:

+
+
+
+
springdoc.remove-broken-reference-definitions=false
+
+
+
+
+

How to override @Deprecated?

+
+

The whole idea of springdoc-openapi is to get your documentation the closest to the code, with minimal code changes. +If the code contains @Deprecated, sprindoc-openapi will consider its schema as Deprecated as well. +If you want to declare a field on swagger as non deprecated, even with the java code, the field contains @Depreacted, +You can use the following property that is available since release v1.4.3:

+
+
+
+
springdoc.model-converters.deprecating-converter.enabled=false
+
+
+
+
+

How can i display a method that returns ModelAndView?

+
+

You can use the following property:

+
+
+
+
springdoc.model-and-view-allowed=true
+
+
+
+
+

How can i have pretty-printed output of the OpenApi specification?

+
+

You can use the following property:

+
+
+
+
springdoc.writer-with-default-pretty-printer=true
+
+
+
+
+

How can i define different schemas for the same class?

+
+

Complex objects are always resolved as a reference to a schema defined in components. +For example let’s consider a Instance class with an workAddress and homeAddress attribute of type Address:

+
+
+
+
public class PersonDTO {
+
+	@JsonProperty
+	private String email;
+
+	@JsonProperty
+	private String firstName;
+
+	@JsonProperty
+	private String lastName;
+
+	@Schema(ref = "WorkAddressSchema")
+	@JsonProperty
+	private Address workAddress;
+
+	@Schema(ref = "HomeAddressSchema")
+	@JsonProperty
+	private Address homeAddress;
+
+}
+
+public class Address {
+
+	@JsonProperty
+	private String addressName;
+
+}
+
+
+
+
+

If you want to define two different schemas for this class, you can set up 2 different schemas as follow:

+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+return new OpenAPI().components(new Components()
+.addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address" ))
+.addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address" )));
+}
+
+private Schema getSchemaWithDifferentDescription(Class className, String description){
+ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+.resolveAsResolvedSchema(
+new AnnotatedType(className).resolveAsRef(false));
+return resolvedSchema.schema.description(description);
+}
+
+
+
+
+
+

How can i define different description for a class attribute depending on usage?

+
+

For example let’s consider a Instance class with an email attribute:

+
+
+
+
public class PersonDTO {
+
+	@JsonProperty
+	private String email;
+
+	@JsonProperty
+	private String firstName;
+
+	@JsonProperty
+	private String lastName;
+
+
+}
+
+
+
+
+

If you want to define two different description for the email, you can set up 2 different schemas as follow:

+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+return new OpenAPI().components(new Components()
+.addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email" ))
+.addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email" )));
+}
+
+private Schema getFieldSchemaWithDifferentDescription(Class className, String description){
+    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+            .resolveAsResolvedSchema(
+                    new AnnotatedType(className).resolveAsRef(false));
+    return resolvedSchema.schema.addProperties("email", new StringSchema().description(description));
+}
+
+
+
+
+
+

Customizing swagger static resources

+
+

You can customize swagger documentation static resources located in META-INF/resources/webjars/swagger-ui/{swagger.version}/. The list of resources includes:

+
+
+
    +
  • +

    index.html

    +
  • +
  • +

    swagger-ui-bundle.js

    +
  • +
  • +

    swagger-ui.css

    +
  • +
  • +

    swagger-ui-standalone-preset.js

    +
  • +
  • +

    swagger-ui.css.map

    +
  • +
  • +

    swagger-ui-bundle.js.map

    +
  • +
  • +

    swagger-ui-standalone-preset.js.map

    +
  • +
  • +

    favicon-32x32.png

    +
  • +
+
+
+

To do this, you need to extend the implementation of SwaggerIndexPageTransformer

+
+
+
+
public class SwaggerCodeBlockTransformer
+       extends SwaggerIndexPageTransformer {
+  // < constructor >
+  @Override
+  public Resource transform(HttpServletRequest request,
+                            Resource resource,
+                            ResourceTransformerChain transformer)
+                            throws IOException {
+      if (resource.toString().contains("swagger-ui.css")) {
+          final InputStream is = resource.getInputStream();
+          final InputStreamReader isr = new InputStreamReader(is);
+          try (BufferedReader br = new BufferedReader(isr)) {
+              final String css = br.lines().collect(Collectors.joining());
+              final byte[] transformedContent = css.replace("old", "new").getBytes();
+              return  new TransformedResource(resource, transformedContent);
+          } // AutoCloseable br > isr > is
+      }
+      return super.transform(request, resource, transformer);
+  }
+
+}
+
+
+
+
+

Next, add transformer @Bean to your @Configuration

+
+
+
+
@Configuration
+public class OpenApiConfig {
+    @Bean
+    public SwaggerIndexTransformer swaggerIndexTransformer(
+            SwaggerUiConfigProperties a,
+            SwaggerUiOAuthProperties b,
+            SwaggerUiConfigParameters c,
+            SwaggerWelcomeCommon d) {
+        return new SwaggerCodeBlockTransformer(a, b, c, d);
+    }
+}
+
+
+
+
+

Illustrative example

+
+
+
+Illustrative example +
+
+
+
+

Is GraalVM supported ?

+
+

The native support available added in spring-boot 3. +If you have some time, do not hesitate to test it before the next release.

+
+
+

For the OpenAPI REST endpoints, you just need to build your application with the spring native profile.

+
+
+

If you give @OpenAPIDefinition or @SecurityScheme to a class that has no implementation, that class will disappear when you natively compile. +To avoid this, give the class a @Configuration.

+
+
+
+
@Configuration
+@OpenAPIDefinition(info = @Info(title = "My App", description = "description"))
+public class OpenAPIConfig {
+}
+
+
+
+
+

How to Integrate Open API 3 with Spring project (not Spring Boot)?

+
+

When your application is using spring without (spring-boot), you need to add beans and auto-configuration that are natively provided in spring-boot.

+
+
+

For example, lets assume you want load the swagger-ui in spring-mvc application:

+
+
+
    +
  • +

    You mainly, need to add the springdoc-openapi module

    +
  • +
+
+
+
+
<dependency>
+   <groupId>org.springdoc</groupId>
+   <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+   <version>last.version</version>
+</dependency>
+
+
+
+
    +
  • +

    If you don’t have the spring-boot and spring-boot-autoconfigure dependencies, you need to add them. And pay attention to the compatibility matrix, between you spring.version and spring-boot.version. For example, in this case (spring.version=5.1.12.RELEASE):

    +
  • +
+
+
+
+
		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-autoconfigure</artifactId>
+			<version>3.3.3</version>
+		</dependency>
+
+
+
+
    +
  • +

    Scan for the springdoc-openapi 'auto-configuration classes that spring-boot automatically loads for you.

    +
  • +
  • +

    Depending on your module, you can find them on the file: spring.factories of each springdoc-openapi module.

    +
  • +
+
+
+
+
@Configuration
+@EnableWebMvc
+public class WebConfig implements WebApplicationInitializer {
+
+	@Override
+	public void onStartup(ServletContext servletContext)  {
+		WebApplicationContext context = getContext();
+		servletContext.addListener(new ContextLoaderListener(context));
+		ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet",
+				new DispatcherServlet(context));
+		dispatcher.setLoadOnStartup(1);
+		dispatcher.addMapping("/*");
+	}
+
+	private AnnotationConfigWebApplicationContext getContext() {
+		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+		context.register(this.getClass(),
+				SpringDocConfiguration.class,
+				SpringDocConfigProperties.class,
+				SpringDocSpecPropertiesConfiguration.class,
+				SpringDocWebMvcConfiguration.class,
+				MultipleOpenApiSupportConfiguration.class,
+				SwaggerConfig.class,
+				SwaggerUiConfigProperties.class,
+				SwaggerUiOAuthProperties.class,
+		);
+		return context;
+	}
+}
+
+
+
+
+
    +
  • +

    Depending on your module, you can find them on the file: org.springframework.boot.autoconfigure.AutoConfiguration.imports of each springdoc-openapi module.

    +
  • +
  • +

    For groups usage make sure your GroupedOpenApi Beans are scanned.

    +
  • +
  • +

    If additionally, you are using custom context path: /my-servlet-path. Make sure you declare the following property:

    +
  • +
+
+
+
+
spring.mvc.servlet.path=/my-servlet-path
+
+
+
+
+

What is the compatibility matrix of springdoc-openapi with spring-boot ?

+
+

springdoc-openapi 2.x is compatible with spring-boot 3.

+
+
+

In general, you should only pick the last stable version as per today 2.8.9.

+
+
+

More precisely, this the exhaustive list of spring-boot versions against which springdoc-openapi has been built:

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

Spring Boot Versions

Springdoc OpenAPI Versions

3.4.x

2.7.x - 2.8.x

3.3.x

2.6.x

3.2.x

2.3.x - 2.5.x

3.1.x

2.2.x

3.0.x

2.0.x - 2.1.x

2.7.x, 1.5.x

1.6.0+

2.6.x, 1.5.x

1.6.0+

2.5.x, 1.5.x

1.5.9+

2.4.x, 1.5.x

1.5.0+

2.3.x, 1.5.x

1.4.0+

2.2.x, 1.5.x

1.2.1+

2.0.x, 1.5.x

1.0.0+

+
+
+

Why am i getting an error: Swagger UI unable to render definition, when overriding the default spring registered HttpMessageConverter?

+
+

When overriding the default spring-boot registered HttpMessageConverter, you should have ByteArrayHttpMessageConverter registered as well to have proper springdoc-openapi support.

+
+
+
+
    converters.add(new ByteArrayHttpMessageConverter());
+    converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder.build()));
+
+
+
+
+ + + + + +
+ + +Order is very important, when registering HttpMessageConverters. +
+
+
+
+

Some parameters are not generated in the resulting OpenAPI spec.

+
+

The issue is caused by the changes introduced by Spring-Boot 3.2.0 +in particular for the Parameter Name Discovery. +This can be fixed by adding the -parameters arg to the Maven Compiler Plugin.

+
+
+
+
<plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <configuration>
+        <parameters>true</parameters>
+    </configuration>
+</plugin>
+
+
+
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000..45468e6 Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/features.html b/docs/features.html new file mode 100644 index 0000000..dfa5983 --- /dev/null +++ b/docs/features.html @@ -0,0 +1,362 @@ + + + + + + + +Springdoc-openapi Features + + + + + + +
+
+
+ +
+
+

Springdoc-openapi Features

+
+
+

Adding API Information and Security documentation

+
+

The library uses spring-boot application auto-configured packages to scan for the following annotations in spring beans: OpenAPIDefinition and Info. +These annotations declare, API Information: Title, version, licence, security, servers, tags, security and externalDocs. +For better performance of documentation generation, declare @OpenAPIDefinition and @SecurityScheme annotations within a spring managed bean.

+
+
+
+

Error Handling for REST using @ControllerAdvice

+
+

To generate documentation automatically, make sure all the methods declare the HTTP Code responses using the annotation: @ResponseStatus

+
+
+
+

Disabling the springdoc-openapi endpoints

+
+

In order to disable the springdoc-openapi endpoint (/v3/api-docs by default) use the following property:

+
+
+
+
# Disabling the /v3/api-docs endpoint
+springdoc.api-docs.enabled=false
+
+
+
+
+

Disabling the swagger-ui

+
+

In order to disable the swagger-ui, use the following property:

+
+
+
+
# Disabling the swagger-ui
+springdoc.swagger-ui.enabled=false
+
+
+
+
+

Swagger-ui configuration

+
+

The library supports the swagger-ui official properties:

+
+ +
+

You need to declare swagger-ui properties as spring-boot properties. +All these properties should be declared with the following prefix: springdoc.swagger-ui

+
+
+
+

Selecting the Rest Controllers to include in the documentation

+
+

Additionally, to @Hidden annotation from swagger-annotations, its possible to restrict the generated OpenAPI description using package or path configuration.

+
+
+

For the list of packages to include, use the following property:

+
+
+
+
# Packages to include
+springdoc.packagesToScan=com.package1, com.package2
+
+
+
+

For the list of paths to include, use the following property:

+
+
+
+
# Paths to include
+springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
+

Spring-webflux/WebMvc.fn with Functional Endpoints

+
+

Since version v1.5.0, a functional DSL has been introduced, thanks to this enhancement in the spring-framework: #25938

+
+
+

It’s an alternative functional API to the @RouterOperations annotations.

+
+
+

This is a sample DSL, to generate OpenAPI description to the webflux/WebMvc.fn REST endpoints:

+
+
+
+
@Bean
+RouterFunction<?> routes() {
+    return route().GET("/foo", HANDLER_FUNCTION, ops -> ops
+            .operationId("hello")
+            .parameter(parameterBuilder().name("key1").description("My key1 description"))
+            .parameter(parameterBuilder().name("key2").description("My key2 description"))
+            .response(responseBuilder().responseCode("200").description("This is normal response description"))
+            .response(responseBuilder().responseCode("404").description("This is another response description"))
+    ).build();
+}
+
+
+
+
+

Here is the link for some sample codes:

+
+ +
+

And the Demo code, using the functional endpoints DSL:

+
+ +
+

Since version v1.3.8, the support of functional endpoints has been added. +Two main annotations have been added for this purpose: @RouterOperations and @RouterOperation.

+
+
+

Only REST APIs with the @RouterOperations and @RouterOperation can be displayed on the swagger-ui.

+
+
+
    +
  • +

    @RouterOperation: It can be used alone, if the Router bean contains one single route related to the REST API.. +When using @RouterOperation, its not mandatory to fill the path

    +
  • +
  • +

    @RouterOperation, can reference directly a spring Bean (beanClass property) and the underlying method (beanMethod property): Springdoc-openapi, will then inspect this method and the swagger annotations on this method level.

    +
  • +
+
+
+
+
@Bean
+@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees")
+RouterFunction<ServerResponse> getAllEmployeesRoute() {
+   return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)),
+         req -> ok().body(
+               employeeService().findAllEmployees(), Employee.class));
+}
+
+
+
+
+
    +
  • +

    @RouterOperation, contains the @Operation annotation. +The @Operation annotation can also be placed on the bean method level if the property beanMethod is declared.

    +
  • +
+
+
+ + + + + +
+ + +Don’t forget to set operationId which is mandatory. +
+
+
+
+
@Bean
+@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" },
+      parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") },
+      responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))),
+            @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"),
+            @ApiResponse(responseCode = "404", description = "Employee not found") }))
+RouterFunction<ServerResponse> getEmployeeByIdRoute() {
+   return route(GET("/employees/{id}"),
+         req -> ok().body(
+               employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
+}
+
+
+
+
+
    +
  • +

    @RouterOperations: This annotation should be used if the Router bean contains multiple routes. +When using RouterOperations, its mandatory to fill the path property.

    +
  • +
  • +

    A @RouterOperations, contains many @RouterOperation.

    +
  • +
+
+
+
+
@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
+      @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
+      @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
+      @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
+@Bean
+public RouterFunction<ServerResponse> personRoute(PersonHandler handler) {
+   return RouterFunctions
+         .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
+         .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
+         .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
+         .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
+}
+
+
+
+
+

All the documentations filled using @RouterOperation, might be completed by the router function data. +For that, @RouterOperation fields must help identify uniquely the concerned route. +springdoc-openpi scans for a unique route related to a @RouterOperation annotation, using on the following criteria:

+
+
+
    +
  • +

    by path

    +
  • +
  • +

    by path and RequestMethod

    +
  • +
  • +

    by path and produces

    +
  • +
  • +

    by path and consumes

    +
  • +
  • +

    by path and RequestMethod and produces

    +
  • +
  • +

    by path and RequestMethod and consumes

    +
  • +
  • +

    by path and produces and consumes

    +
  • +
  • +

    by path and RequestMethod and produces and consumes

    +
  • +
+
+
+

Some code samples are available on GITHUB of demos:

+
+ +
+

And some project tests: (from app69 to app75)

+
+ +
+
+

Integration with WildFly

+
+
    +
  • +

    For WildFly users, you need to add the following dependency to make the swagger-ui work:

    +
  • +
+
+
+
+
   <dependency>
+     <groupId>org.webjars</groupId>
+     <artifactId>webjars-locator-jboss-vfs</artifactId>
+     <version>0.1.0</version>
+   </dependency>
+
+
+ + + +
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/fonts/FontAwesome.otf b/docs/fonts/FontAwesome.otf new file mode 100755 index 0000000..401ec0f Binary files /dev/null and b/docs/fonts/FontAwesome.otf differ diff --git a/docs/fonts/fontawesome-webfont.eot b/docs/fonts/fontawesome-webfont.eot new file mode 100755 index 0000000..e9f60ca Binary files /dev/null and b/docs/fonts/fontawesome-webfont.eot differ diff --git a/docs/fonts/fontawesome-webfont.svg b/docs/fonts/fontawesome-webfont.svg new file mode 100755 index 0000000..855c845 --- /dev/null +++ b/docs/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/fonts/fontawesome-webfont.ttf b/docs/fonts/fontawesome-webfont.ttf new file mode 100755 index 0000000..35acda2 Binary files /dev/null and b/docs/fonts/fontawesome-webfont.ttf differ diff --git a/docs/fonts/fontawesome-webfont.woff b/docs/fonts/fontawesome-webfont.woff new file mode 100755 index 0000000..400014a Binary files /dev/null and b/docs/fonts/fontawesome-webfont.woff differ diff --git a/docs/fonts/fontawesome-webfont.woff2 b/docs/fonts/fontawesome-webfont.woff2 new file mode 100755 index 0000000..4d13fc6 Binary files /dev/null and b/docs/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/getting-started.html b/docs/getting-started.html new file mode 100644 index 0000000..448bf29 --- /dev/null +++ b/docs/getting-started.html @@ -0,0 +1,117 @@ + + + + + + + +Getting Started + + + + + + +
+
+
+ +
+
+

Getting Started

+
+
+

For the integration between spring-boot and swagger-ui, add the library to the list of your project dependencies (No additional configuration is needed)

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+      <version>2.8.9</version>
+   </dependency>
+
+
+
+

This will automatically deploy swagger-ui to a spring-boot application:

+
+
+
    +
  • +

    Documentation will be available in HTML format, using the official swagger-ui jars

    +
  • +
  • +

    The Swagger UI page will then be available at http://server:port/context-path/swagger-ui.html and the OpenAPI description will be available at the following url for json format: http://server:port/context-path/v3/api-docs

    +
    +
      +
    • +

      server: The server name or IP

      +
    • +
    • +

      port: The server port

      +
    • +
    • +

      context-path: The context path of the application

      +
    • +
    +
    +
  • +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
+
+
+ + + + + +
+ + +For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: . +
+
+
+
+
# swagger-ui custom path
+springdoc.swagger-ui.path=/swagger-ui.html
+
+
+ + + +
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/img/LVM_Versicherung_2010_logo.svg.png b/docs/img/LVM_Versicherung_2010_logo.svg.png new file mode 100644 index 0000000..5aac7e9 Binary files /dev/null and b/docs/img/LVM_Versicherung_2010_logo.svg.png differ diff --git a/docs/img/banner-logo.svg b/docs/img/banner-logo.svg new file mode 100644 index 0000000..aeb97b5 --- /dev/null +++ b/docs/img/banner-logo.svg @@ -0,0 +1,85 @@ + + + + + +Created with Fabric.js 4.6.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OpenAPI 3&Spring Boot + + \ No newline at end of file diff --git a/assets/images/common.jpg b/docs/img/common.jpg similarity index 100% rename from assets/images/common.jpg rename to docs/img/common.jpg diff --git a/docs/img/common.png b/docs/img/common.png new file mode 100644 index 0000000..0fc4efe Binary files /dev/null and b/docs/img/common.png differ diff --git a/docs/img/contrastsecurity.svg b/docs/img/contrastsecurity.svg new file mode 100644 index 0000000..21cd538 --- /dev/null +++ b/docs/img/contrastsecurity.svg @@ -0,0 +1,17 @@ + + + Contrast_Logo_RGB + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/img/dmTECH_Logo.jpg b/docs/img/dmTECH_Logo.jpg new file mode 100644 index 0000000..470b6fb Binary files /dev/null and b/docs/img/dmTECH_Logo.jpg differ diff --git a/docs/img/doc-background-dark.svg b/docs/img/doc-background-dark.svg new file mode 100755 index 0000000..3e7b63c --- /dev/null +++ b/docs/img/doc-background-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/img/doc-background.svg b/docs/img/doc-background.svg new file mode 100755 index 0000000..301ff34 --- /dev/null +++ b/docs/img/doc-background.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docs/img/gdnext.png b/docs/img/gdnext.png new file mode 100644 index 0000000..1523834 Binary files /dev/null and b/docs/img/gdnext.png differ diff --git a/docs/img/github-logo.png b/docs/img/github-logo.png new file mode 100644 index 0000000..8b25551 Binary files /dev/null and b/docs/img/github-logo.png differ diff --git a/docs/img/jetbrains.svg b/docs/img/jetbrains.svg new file mode 100644 index 0000000..cb3a2a0 --- /dev/null +++ b/docs/img/jetbrains.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/img/mercedes-benz.png b/docs/img/mercedes-benz.png new file mode 100644 index 0000000..38a46ef Binary files /dev/null and b/docs/img/mercedes-benz.png differ diff --git a/docs/img/octicons-16.svg b/docs/img/octicons-16.svg new file mode 100755 index 0000000..9e8fe28 --- /dev/null +++ b/docs/img/octicons-16.svg @@ -0,0 +1,109 @@ + + Octicons (24px subset) + Octicons v12.1.0 by GitHub - https://primer.style/octicons/ - License: MIT + + + + @primer/octicons + 12.1.0 + A scalable set of icons handcrafted with <3 by GitHub + image/svg+xml + + + GitHub + + + + + Copyright (c) 2020 GitHub Inc. + + + + https://primer.style/octicons/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/pets.png b/docs/img/pets.png similarity index 100% rename from assets/images/pets.png rename to docs/img/pets.png diff --git a/docs/img/spring-io-24.png b/docs/img/spring-io-24.png new file mode 100644 index 0000000..4aca7cf Binary files /dev/null and b/docs/img/spring-io-24.png differ diff --git a/assets/images/springdoc-openapi-conf.gif b/docs/img/springdoc-openapi-conf.gif similarity index 100% rename from assets/images/springdoc-openapi-conf.gif rename to docs/img/springdoc-openapi-conf.gif diff --git a/assets/images/springdoc-openapi-prez.gif b/docs/img/springdoc-openapi-prez.gif similarity index 100% rename from assets/images/springdoc-openapi-prez.gif rename to docs/img/springdoc-openapi-prez.gif diff --git a/docs/img/springdoc-openapi.png b/docs/img/springdoc-openapi.png new file mode 100644 index 0000000..a244f90 Binary files /dev/null and b/docs/img/springdoc-openapi.png differ diff --git a/docs/img/springdoc/springdoc-favicon.svg b/docs/img/springdoc/springdoc-favicon.svg new file mode 100644 index 0000000..21eeef6 --- /dev/null +++ b/docs/img/springdoc/springdoc-favicon.svg @@ -0,0 +1,166 @@ + + + + Created with Fabric.js 4.6.0 diff --git a/docs/img/springdoc/springdoc-logo.svg b/docs/img/springdoc/springdoc-logo.svg new file mode 100644 index 0000000..f3f7bb8 --- /dev/null +++ b/docs/img/springdoc/springdoc-logo.svg @@ -0,0 +1,139 @@ + + + + Created with Fabric.js 4.6.0 diff --git a/docs/img/static_content_transformation.png b/docs/img/static_content_transformation.png new file mode 100644 index 0000000..edcc70d Binary files /dev/null and b/docs/img/static_content_transformation.png differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..d4d6b74 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,4711 @@ + + + + + + + + +OpenAPI 3 Library for spring-boot + +OpenAPI 3 Library for spring-boot + + + + + + + + + +springdoc-openapi v2.8.9 + + + + + + + + + + + +
+
+
+ +
+
+
+
+ + + + + +
+ + +springdoc-openapi v1.8.0 is the latest Open Source release supporting Spring Boot 2.x and 1.x.
+An extended support for springdoc-openapi v1 project is now available for organizations that need support beyond 2023.
+For more details, feel free to reach out: sales@springdoc.org +
+
+
+

springdoc-openapi is on Open Collective. If you ❤️ this project consider becoming a sponsor.

+
+
+

This project is sponsored by

+
+

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

+ +
+
+
+

1. Introduction

+
+
+

springdoc-openapi java library helps to automate the generation of API documentation using spring boot projects. +springdoc-openapi works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations.

+
+
+

Automatically generates documentation in JSON/YAML and HTML format APIs. +This documentation can be completed by comments using swagger-api annotations.

+
+
+

This library supports:

+
+
+
    +
  • +

    OpenAPI 3

    +
  • +
  • +

    Spring-boot v3 (Java 17 & Jakarta EE 9)

    +
  • +
  • +

    JSR-303, specifically for @NotNull, @Min, @Max, and @Size.

    +
  • +
  • +

    Swagger-ui

    +
  • +
  • +

    OAuth 2

    +
  • +
  • +

    GraalVM native images

    +
  • +
+
+
+

The following video introduces the Library:

+
+
+
+spring.io conference +
+
+
+

This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal).

+
+
+
+
+

2. Getting Started

+
+
+

For the integration between spring-boot and swagger-ui, add the library to the list of your project dependencies (No additional configuration is needed)

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+      <version>2.8.9</version>
+   </dependency>
+
+
+
+

This will automatically deploy swagger-ui to a spring-boot application:

+
+
+
    +
  • +

    Documentation will be available in HTML format, using the official swagger-ui jars

    +
  • +
  • +

    The Swagger UI page will then be available at http://server:port/context-path/swagger-ui.html and the OpenAPI description will be available at the following url for json format: http://server:port/context-path/v3/api-docs

    +
    +
      +
    • +

      server: The server name or IP

      +
    • +
    • +

      port: The server port

      +
    • +
    • +

      context-path: The context path of the application

      +
    • +
    +
    +
  • +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
+
+
+ + + + + +
+ + +For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: . +
+
+
+
+
# swagger-ui custom path
+springdoc.swagger-ui.path=/swagger-ui.html
+
+
+ + + +
+
+
+

3. Springdoc-openapi Modules

+
+
+

3.1. General overview

+
+
+Architecture +
+
+
+
+

3.2. Spring WebMvc support

+
+
    +
  • +

    Documentation will be available at the following url for json format: http://server:port/context-path/v3/api-docs

    +
    +
      +
    • +

      server: The server name or IP

      +
    • +
    • +

      port: The server port

      +
    • +
    • +

      context-path: The context path of the application

      +
    • +
    +
    +
  • +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
  • +

    Add the library to the list of your project dependencies. (No additional configuration is needed)

    +
  • +
+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
+      <version>2.8.9</version>
+   </dependency>
+
+
+
+ + + + + +
+ + +This dependency is relevant if you want to generate the OpenAPI description without using the swagger-ui. +
+
+
+ + + + + +
+ + +For custom path of the OpenAPI documentation in Json format, add a custom springdoc property, in your spring-boot configuration file: +
+
+
+
+
# /api-docs endpoint custom path
+springdoc.api-docs.path=/api-docs
+
+
+
+
+

3.3. Spring WebFlux support

+
+
    +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
  • +

    Add the library to the list of your project dependencies (No additional configuration is needed)

    +
  • +
+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-starter-webflux-api</artifactId>
+      <version>2.8.9</version>
+   </dependency>
+
+
+
+
+

3.4. Spring Hateoas support

+
+

The support for Spring Hateoas is available using the dependency springdoc-openapi-hateoas.

+
+
+

The projects that use spring-boot-starter-hateoas should use:

+
+
+
    +
  • +

    springdoc-openapi-starter-webmvc-api if they need only the access to the OpenAPI endpoints

    +
  • +
  • +

    OR springdoc-openapi-starter-webmvc-ui, if they need also the access to the swagger-ui

    +
  • +
+
+
+
+

3.5. Spring Data Rest support

+
+

springdoc-openapi project supports spring-boot-starter-data-rest types like: @RepositoryRestResource and QuerydslPredicate annotations.

+
+
+

The projects that use spring-boot-starter-data-rest should use:

+
+
+
    +
  • +

    springdoc-openapi-starter-webmvc-api if they need only the access to the OpenAPI endpoints

    +
  • +
  • +

    OR springdoc-openapi-starter-webmvc-ui, if they need also the access to the swagger-ui

    +
  • +
+
+
+
+

3.6. Spring Security support

+
+

springdoc-openapi helps ignoring @AuthenticationPrincipal type in case it is used on REST Controllers.

+
+
+

springdoc-openapi supports also exposing Oauth2 endpoints of spring-security-oauth2-authorization-server.

+
+
+

The projects that use spring-boot-starter-security or spring-security-oauth2-authorization-server should use:

+
+
+
    +
  • +

    springdoc-openapi-starter-webmvc-api if they depend on spring-boot-starter-web and they only need the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webmvc-ui, if they depend on spring-boot-starter-web and they also need the access to the swagger-ui.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-api if they depend on spring-boot-starter-webflux and they only the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-ui, if they depend on spring-boot-starter-webflux and they also need the access to the swagger-ui.

    +
  • +
+
+
+
+

3.7. Actuator support

+
+
    +
  • +

    In order to display spring-boot-actuator endpoints, simply add the following property:

    +
  • +
+
+
+
+
springdoc.show-actuator=true
+
+
+
+

Starting from the release 1.5.1, it will be possible to expose the swagger-ui and the openapi endpoints on actuator port.

+
+
+ + + + + +
+ + +The actuator management port has to be different from the application port. +
+
+
+

To expose the swagger-ui, on the management port, you should set

+
+
+
+
springdoc.use-management-port=true
+# This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path.
+management.endpoints.web.exposure.include=openapi, swagger-ui
+
+
+
+

Once enabled, you should also be able to see the springdoc-openapi endpoints under: (host and port depends on your settings) +- http://serverName:managementPort/actuator

+
+
+

For example, if you have the following settings:

+
+
+

Two endpoints will be available:

+
+
+
    +
  1. +

    REST API that holdes the OpenAPI definition:

    +
    +
      +
    • +

      http://serverName:managementPort/actuator/openapi

      +
    • +
    +
    +
  2. +
  3. +

    An Endpoint, that routes to the swagger-ui:

    +
    +
      +
    • +

      http://serverName:managementPort/actuator/swagger-ui

      +
    • +
    +
    +
  4. +
+
+
+
+
management.server.port=9090
+
+
+
+

For the example, you should also be able to see the springdoc-openapi endpoints:

+
+
+
    +
  • +

    http://serverName:9090/actuator

    +
  • +
  • +

    http://serverName:9090/actuator/swagger-ui

    +
  • +
  • +

    http://serverName:9090/actuator/openapi

    +
  • +
+
+
+

All the path springdoc-openapi properties are not applicable when springdoc.use-management-port=true.

+
+
+ + + + + +
+ + +If you want to reach the application endpoints, from the swagger-ui deployed beneath the actuator base path, using a different port from your application, CORS for your endpoints on your application level should be enabled. +
+
+
+

Additionally, it is also possible to combine this property, with the existing property to display the actuator endpoints in the swagger-ui.

+
+
+
+
springdoc.show-actuator=true
+
+
+
+

Once enabled: +- A dedicated group for the actuator endpoints will be by default added. +- If no group is defined for the application, a default one will be added.

+
+
+

The swagger-ui will be then accessible through the actuator port:

+
+
+
    +
  • +

    http://serverName:managementPort/actuator/swagger-ui

    +
  • +
+
+
+

If the management port is different from the application port and springdoc.use-management-port is not defined but springdoc.show-actuator is set to true:

+
+
+
    +
  • +

    The swagger-ui will be then accessible through the application port. For example: http://serverName:applicationPort/swagger-ui.html

    +
  • +
  • +

    A dedicated group for the actuator endpoints will be by default added.

    +
  • +
  • +

    If no group is defined for the application, a default one will be added.

    +
  • +
+
+
+ + + + + +
+ + +If you want to reach the actuator endpoints for this case (different port from your application), CORS for your actuator endpoints should be enabled. +
+
+
+

Note: The naming of these new endpoints beneath the actuator base path cannot be customized for now.

+
+
+
+

3.8. Spring Cloud Function Web support

+
+

spring-cloud-function-web exposes Java Function as REST endpoint automatically. +* Since version v1.6.3, the support of functional endpoints has been added.

+
+
+
    +
  • +

    These starters will display the OpenAPI description of the spring-cloud-function-web endpoints.

    +
    +
      +
    • +

      If you are using spring-web, simply add the springdoc-openapi-starter-webmvc-ui dependency.

      +
    • +
    • +

      If you are using spring-webflux, simply add the springdoc-openapi-starter-webflux-ui dependency.

      +
    • +
    +
    +
  • +
+
+
+

The customisation of the output can be achieved programmatically through OpenApiCustomizer or with the annotations: @RouterOperations and @RouterOperation. +For annotation usage, you have: +* @RouterOperation: It can be used alone, if the customisation is related to a single REST API. +When using @RouterOperation, it’s not mandatory to fill the path

+
+
+
    +
  • +

    @RouterOperation, contains the @Operation annotation. +The @Operation annotation can also be placed on the bean method level if the property beanMethod is declared.

    +
  • +
+
+
+ + + + + +
+ + +Don’t forget to set operationId which is mandatory. +
+
+
+
+
@Bean
+@RouterOperation(operation = @Operation(description = "Say hello", operationId = "hello", tags = "persons",
+        responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = PersonDTO.class)))))
+public Supplier<PersonDTO> helloSupplier() {
+    return () -> new PersonDTO();
+}
+
+
+
+
+
    +
  • +

    @RouterOperations: This annotation should be used to describe the multiple REST APIs exposed by spring-cloud-function-web. +When using RouterOperations, it’s mandatory to fill the method property.

    +
  • +
  • +

    A @RouterOperations, contains many @RouterOperation.

    +
  • +
+
+
+
+
@Bean
+@RouterOperations({
+        @RouterOperation(method = RequestMethod.GET, operation = @Operation(description = "Say hello GET", operationId = "lowercaseGET", tags = "persons")),
+        @RouterOperation(method = RequestMethod.POST, operation = @Operation(description = "Say hello POST", operationId = "lowercasePOST", tags = "positions"))
+})
+public Function<Flux<String>, Flux<String>> lowercase() {
+    return flux -> flux.map(value -> value.toLowerCase());
+}
+
+
+
+
+

Some code samples are available on GITHUB of demos:

+
+ +
+
+

3.9. Kotlin support

+
+

springdoc-openapi supports Kotlin types.

+
+
+

The projects that use Kotlin should use:

+
+
+
    +
  • +

    springdoc-openapi-starter-webmvc-api if they depend on spring-boot-starter-web and they only need the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webmvc-ui, if they depend on spring-boot-starter-web and they also need the access to the swagger-ui.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-api if they depend on spring-boot-starter-webflux and they only the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-ui, if they depend on spring-boot-starter-webflux and they also need the access to the swagger-ui.

    +
  • +
+
+
+ + + + + +
+ + +In addition, your project should add jackson-module-kotlin as well to have the full support of Kotlin types: +
+
+
+
+
    <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-kotlin</artifactId>
+    </dependency>
+
+
+
+
+

3.10. Groovy support

+
+

The projects that use Groovy should use:

+
+
+
    +
  • +

    springdoc-openapi-starter-webmvc-api if they depend on spring-boot-starter-web and they only need the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webmvc-ui, if they depend on spring-boot-starter-web and they also need the access to the swagger-ui.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-api if they depend on spring-boot-starter-webflux and they only the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-ui, if they depend on spring-boot-starter-webflux and they also need the access to the swagger-ui.

    +
  • +
+
+
+
+

3.11. Javadoc support

+
+

springdoc-openapi can introspect Javadoc annotations and comments:

+
+
+
    +
  • +

    The javadoc comment of a method: is resolved as the @Operation description

    +
  • +
  • +

    @return : is resolved as the @Operation response description

    +
  • +
  • +

    The javadoc comment of an attribute: is resolved as '@Schema' description for this field.

    +
  • +
+
+
+

The projects that needs Javadoc support should use:

+
+
+
    +
  • +

    springdoc-openapi-starter-webmvc-api if they depend on spring-boot-starter-web and they only need the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webmvc-ui, if they depend on spring-boot-starter-web and they also need the access to the swagger-ui.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-api if they depend on spring-boot-starter-webflux and they only the access to the OpenAPI endpoints.

    +
  • +
  • +

    OR springdoc-openapi-starter-webflux-ui, if they depend on spring-boot-starter-webflux and they also need the access to the swagger-ui.

    +
  • +
+
+
+ + + + + +
+ + +In addition, your project should add therapi-runtime-javadoc to read Javadoc comments at runtime. +Ensure that you add it as well as its annotation processor to your project’s dependencies. Otherwise, the Javadoc support will fail silently. +
+
+
+
+
    <!--Annotation processor -->
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>com.github.therapi</groupId>
+                            <artifactId>therapi-runtime-javadoc-scribe</artifactId>
+                            <version>0.15.0</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!-- Runtime library -->
+    <dependency>
+        <groupId>com.github.therapi</groupId>
+        <artifactId>therapi-runtime-javadoc</artifactId>
+        <version>0.15.0</version>
+    </dependency>
+
+
+
+ + + + + +
+ + +If both a swagger-annotation description and a javadoc comment are present. The value of the swagger-annotation description will be used. +
+
+
+
+

3.12. Springdoc-openapi BOM

+
+

Starting from version v2.8.7, springdoc-openapi provides a BOM (Bill of Materials) to manage the dependencies of the project. +You can declare it in your project as follows:

+
+
+
+
    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springdoc</groupId>
+                <artifactId>springdoc-openapi-bom</artifactId>
+                <version>2.8.9</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+
+
+
+
+
+

4. Springdoc-openapi Features

+
+
+

4.1. Adding API Information and Security documentation

+
+

The library uses spring-boot application auto-configured packages to scan for the following annotations in spring beans: OpenAPIDefinition and Info. +These annotations declare, API Information: Title, version, licence, security, servers, tags, security and externalDocs. +For better performance of documentation generation, declare @OpenAPIDefinition and @SecurityScheme annotations within a spring managed bean.

+
+
+
+

4.2. Error Handling for REST using @ControllerAdvice

+
+

To generate documentation automatically, make sure all the methods declare the HTTP Code responses using the annotation: @ResponseStatus

+
+
+
+

4.3. Disabling the springdoc-openapi endpoints

+
+

In order to disable the springdoc-openapi endpoint (/v3/api-docs by default) use the following property:

+
+
+
+
# Disabling the /v3/api-docs endpoint
+springdoc.api-docs.enabled=false
+
+
+
+
+

4.4. Disabling the swagger-ui

+
+

In order to disable the swagger-ui, use the following property:

+
+
+
+
# Disabling the swagger-ui
+springdoc.swagger-ui.enabled=false
+
+
+
+
+

4.5. Swagger-ui configuration

+
+

The library supports the swagger-ui official properties:

+
+ +
+

You need to declare swagger-ui properties as spring-boot properties. +All these properties should be declared with the following prefix: springdoc.swagger-ui

+
+
+
+

4.6. Selecting the Rest Controllers to include in the documentation

+
+

Additionally, to @Hidden annotation from swagger-annotations, its possible to restrict the generated OpenAPI description using package or path configuration.

+
+
+

For the list of packages to include, use the following property:

+
+
+
+
# Packages to include
+springdoc.packagesToScan=com.package1, com.package2
+
+
+
+

For the list of paths to include, use the following property:

+
+
+
+
# Paths to include
+springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
+

4.7. Spring-webflux/WebMvc.fn with Functional Endpoints

+
+

Since version v1.5.0, a functional DSL has been introduced, thanks to this enhancement in the spring-framework: #25938

+
+
+

It’s an alternative functional API to the @RouterOperations annotations.

+
+
+

This is a sample DSL, to generate OpenAPI description to the webflux/WebMvc.fn REST endpoints:

+
+
+
+
@Bean
+RouterFunction<?> routes() {
+    return route().GET("/foo", HANDLER_FUNCTION, ops -> ops
+            .operationId("hello")
+            .parameter(parameterBuilder().name("key1").description("My key1 description"))
+            .parameter(parameterBuilder().name("key2").description("My key2 description"))
+            .response(responseBuilder().responseCode("200").description("This is normal response description"))
+            .response(responseBuilder().responseCode("404").description("This is another response description"))
+    ).build();
+}
+
+
+
+
+

Here is the link for some sample codes:

+
+ +
+

And the Demo code, using the functional endpoints DSL:

+
+ +
+

Since version v1.3.8, the support of functional endpoints has been added. +Two main annotations have been added for this purpose: @RouterOperations and @RouterOperation.

+
+
+

Only REST APIs with the @RouterOperations and @RouterOperation can be displayed on the swagger-ui.

+
+
+
    +
  • +

    @RouterOperation: It can be used alone, if the Router bean contains one single route related to the REST API.. +When using @RouterOperation, its not mandatory to fill the path

    +
  • +
  • +

    @RouterOperation, can reference directly a spring Bean (beanClass property) and the underlying method (beanMethod property): Springdoc-openapi, will then inspect this method and the swagger annotations on this method level.

    +
  • +
+
+
+
+
@Bean
+@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees")
+RouterFunction<ServerResponse> getAllEmployeesRoute() {
+   return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)),
+         req -> ok().body(
+               employeeService().findAllEmployees(), Employee.class));
+}
+
+
+
+
+
    +
  • +

    @RouterOperation, contains the @Operation annotation. +The @Operation annotation can also be placed on the bean method level if the property beanMethod is declared.

    +
  • +
+
+
+ + + + + +
+ + +Don’t forget to set operationId which is mandatory. +
+
+
+
+
@Bean
+@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" },
+      parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") },
+      responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))),
+            @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"),
+            @ApiResponse(responseCode = "404", description = "Employee not found") }))
+RouterFunction<ServerResponse> getEmployeeByIdRoute() {
+   return route(GET("/employees/{id}"),
+         req -> ok().body(
+               employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
+}
+
+
+
+
+
    +
  • +

    @RouterOperations: This annotation should be used if the Router bean contains multiple routes. +When using RouterOperations, its mandatory to fill the path property.

    +
  • +
  • +

    A @RouterOperations, contains many @RouterOperation.

    +
  • +
+
+
+
+
@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
+      @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
+      @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
+      @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
+@Bean
+public RouterFunction<ServerResponse> personRoute(PersonHandler handler) {
+   return RouterFunctions
+         .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
+         .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
+         .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
+         .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
+}
+
+
+
+
+

All the documentations filled using @RouterOperation, might be completed by the router function data. +For that, @RouterOperation fields must help identify uniquely the concerned route. +springdoc-openpi scans for a unique route related to a @RouterOperation annotation, using on the following criteria:

+
+
+
    +
  • +

    by path

    +
  • +
  • +

    by path and RequestMethod

    +
  • +
  • +

    by path and produces

    +
  • +
  • +

    by path and consumes

    +
  • +
  • +

    by path and RequestMethod and produces

    +
  • +
  • +

    by path and RequestMethod and consumes

    +
  • +
  • +

    by path and produces and consumes

    +
  • +
  • +

    by path and RequestMethod and produces and consumes

    +
  • +
+
+
+

Some code samples are available on GITHUB of demos:

+
+ +
+

And some project tests: (from app69 to app75)

+
+ +
+
+

4.8. Integration with WildFly

+
+
    +
  • +

    For WildFly users, you need to add the following dependency to make the swagger-ui work:

    +
  • +
+
+
+
+
   <dependency>
+     <groupId>org.webjars</groupId>
+     <artifactId>webjars-locator-jboss-vfs</artifactId>
+     <version>0.1.0</version>
+   </dependency>
+
+
+ + + +
+
+
+
+

5. Springdoc-openapi Properties

+
+
+

springdoc-openapi relies on standard spring configuration properties (yml or properties) using the standard files locations.

+
+
+

5.1. springdoc-openapi core properties

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameDefault ValueDescription

springdoc.api-docs.path

/v3/api-docs

String, For custom path of the OpenAPI documentation in Json format.

springdoc.api-docs.enabled

true

Boolean. To disable the springdoc-openapi endpoint (/v3/api-docs by default).

springdoc.packages-to-scan

*

List of Strings. The list of packages to scan (comma separated)

springdoc.paths-to-match

/*

List of Strings. The list of paths to match (comma separated)

springdoc.produces-to-match

/*

List of Strings. The list of produces mediaTypes to match (comma separated)

springdoc.headers-to-match

/*

List of Strings. The list of headers to match (comma separated)

springdoc.consumes-to-match

/*

List of Strings. The list of consumes mediaTypes to match (comma separated)

springdoc.paths-to-exclude

List of Strings. The list of paths to exclude (comma separated)

springdoc.packages-to-exclude

List of Strings. The list of packages to exclude (comma separated)

springdoc.default-consumes-media-type

application/json

String. The default consumes media type.

springdoc.default-produces-media-type

/

String. The default produces media type.

springdoc.cache.disabled

false

Boolean. To disable the springdoc-openapi cache of the calculated OpenAPI.

springdoc.show-actuator

false

Boolean. To display the actuator endpoints.

springdoc.auto-tag-classes

true

Boolean. To disable the springdoc-openapi automatic tags.

springdoc.model-and-view-allowed

false

Boolean. To allow RestControllers with ModelAndView return to appear in the OpenAPI description.

springdoc.override-with-generic-response

true

Boolean. When true, automatically adds @ControllerAdvice responses to all the generated responses.

springdoc.group-configs[0].group

String. The group name

springdoc.group-configs[0].display-name

String. The display name of the group.

springdoc.group-configs[0].packages-to-scan

*

List of Strings. The list of packages to scan for a group (comma separated)

springdoc.group-configs[0].paths-to-match

/*

List of Strings. The list of paths to match for a group (comma separated)

springdoc.group-configs[0].paths-to-exclude

``

List of Strings. The list of paths to exclude for a group (comma separated)

springdoc.group-configs[0].packages-to-exclude

List of Strings. The list of packages to exclude for a group (comma separated)

springdoc.group-configs[0].produces-to-match

/*

List of Strings. The list of produces mediaTypes to match (comma separated)

springdoc.group-configs[0].consumes-to-match

/*

List of Strings. The list of consumes mediaTypes to match (comma separated)

springdoc.group-configs[0].headers-to-match

/*

List of Strings. The list of headers to match (comma separated)

springdoc.webjars.prefix

/webjars

String. To change the webjars prefix that is visible the URL of swagger-ui for spring-webflux.

springdoc.api-docs.resolve-schema-properties

false

Boolean. To enable property resolver on @Schema (name, title and description).

springdoc.remove-broken-reference-definitions

true

Boolean. To disable removal of broken reference definitions.

springdoc.writer-with-default-pretty-printer

false

Boolean. To enable pretty print of the OpenApi specification.

springdoc.model-converters.deprecating-converter.enabled

true

Boolean. To disable deprecating model converter.

springdoc.model-converters.polymorphic-converter.enabled

true

Boolean. To disable polymorphic model converter.

springdoc.model-converters.pageable-converter.enabled

true

Boolean. To disable pageable model converter.

springdoc.model-converters.sort-converter.enabled

true

Boolean. To disable Sort converter.

springdoc.use-fqn

false

Boolean. To enable fully qualified names.

springdoc.show-login-endpoint

false

Boolean. To make spring security login-endpoint visible.

springdoc.pre-loading-locales

List of Strings. The list of locales to load OpenAPI on application startup (comma separated). If not specified, it will preload with the default Locale.

springdoc.writer-with-order-by-keys

false

Boolean. Enable a deterministic/alphabetical ordering.

springdoc.use-management-port

false

Boolean. To expose the swagger-ui on the actuator management port.

springdoc.disable-i18n

false

Boolean. To disable automatic translation using i18n.

springdoc.show-spring-cloud-functions

true

Boolean. To display the spring-cloud-function web endpoints.

springdoc.enable-groovy

true

Boolean. To enable Groovy support.

springdoc.enable-spring-security

true

Boolean. To enable spring-security support.

springdoc.enable-kotlin

true

Boolean. To enable Kotlin support.

springdoc.enable-hateoas

true

Boolean. To enable spring-hateoas support.

springdoc.enable-data-rest

true

Boolean. To enable spring-data-rest support.

springdoc.api-docs.version

openapi_3_1

String. To choose OpenAPI 3.0 or OpenAPI 3.1 (using the value OPENAPI_3_1).

springdoc.default-flat-param-object

false

Boolean. To default flatten parameter.

springdoc.default-support-form-data

false

Boolean. To default set parameters to form data when specifying api to accept form data.

springdoc.nullable-request-parameter-enabled

true

Boolean. To default Enable Support for nullable request parameters in Kotlin.

springdoc.show-oauth2-endpoints

false

Boolean. To make spring security oauth2-endpoint visible.

springdoc.api-docs.resolve-extensions-properties

false

Boolean. To enable support of spring property resolver for @ExtensionProperty.

springdoc.enable-default-api-docs

true

Boolean. To enable default OpenAPI endpoint /v3/api-docs.

springdoc.trim-kotlin-indent

false

Boolean. Adjust indentation when parsing the @Operation annotation in Kotlin.

springdoc.allowed-locales

List of Strings. The list of allowed locales for OpenAPI (comma separated, for example US,fr-CA).

springdoc.enable-extra-schemas

true

Boolean. To enable default support for extra Schemas, from java.time package like LocalTime, Duration, but also other Java classes like java.util.Locale or java.nio.charset.Charset

springdoc.explicit-object-schema

false

Boolean. Set explicit-object-schema to true to always include type: object in the schema, or to false to omit type: object.

springdoc.use-arbitrary-schemas

false

Boolean. When set to true, schemas without a defined type will be deserialized as an ArbitrarySchema (with no type), instead of an ObjectSchema with type: object.

+
+
+

5.2. swagger-ui properties

+
+
    +
  • +

    The support of the swagger-ui properties is available on springdoc-openapi. See Official documentation.

    +
  • +
  • +

    You can use the same swagger-ui properties in the documentation as Spring Boot properties.

    +
  • +
+
+
+ + + + + +
+ + +All these properties should be declared with the following prefix: springdoc.swagger-ui +
+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameDefault ValueDescription

springdoc.swagger-ui.path

/swagger-ui.html

String, For custom path of the swagger-ui HTML documentation.

springdoc.swagger-ui.enabled

true

Boolean. To disable the swagger-ui endpoint (/swagger-ui.html by default).

springdoc.swagger-ui.configUrl

/v3/api-docs/swagger-config

String. URL to fetch external configuration document from.

springdoc.swagger-ui.layout

BaseLayout

String. The name of a component available via the plugin system to use as the top-level layout for Swagger UI.

springdoc.swagger-ui.validatorUrl

By default, Swagger UI does not validate specs. You can use this parameter to set a validator URL, for example for against swagger.io’s online validator.

springdoc.swagger-ui.tryItOutEnabled

false

Boolean. Controls whether the "Try it out" section should be enabled by default.

springdoc.swagger-ui.filter

false

Boolean OR String. If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be Boolean to enable or disable, or a string, in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.

springdoc.swagger-ui.operationsSorter

Function=(a ⇒ a). Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.

springdoc.swagger-ui.tagsSorter

Function=(a ⇒ a). Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function see Array.prototype.sort() to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger UI.

springdoc.swagger-ui.oauth2RedirectUrl

/swagger-ui/oauth2-redirect.html

String. OAuth redirect URL.

springdoc.swagger-ui.displayOperationId

false

Boolean. Controls the display of operationId in operations list. The default is false.

springdoc.swagger-ui.displayRequestDuration

false

Boolean. Controls the display of the request duration (in milliseconds) for "Try it out" requests.

springdoc.swagger-ui.deepLinking

false

Boolean. If set to true, enables deep linking for tags and operations. See the [Deep Linking documentation](swagger.io/docs/open-source-tools/swagger-ui/usage/deep-linking) for more information.

springdoc.swagger-ui.defaultModelsExpandDepth

1

Number. The default expansion depth for models (set to -1 completely hide the models).

springdoc.swagger-ui.defaultModelExpandDepth

1

Number. The default expansion depth for the model on the model-example section.

springdoc.swagger-ui.defaultModelRendering

String=["example"*, "model"]. Controls how the model is shown when the API is first rendered. (The user can always switch the rendering for a given model by clicking the 'Model' and 'Example Value' links.)

springdoc.swagger-ui.docExpansion

String=["list"*, "full", "none"]. Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing).

springdoc.swagger-ui.maxDisplayedTags

Number. If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.

springdoc.swagger-ui.showExtensions

false

Boolean. Controls the display of vendor extension (x-) fields and values for Operations, Parameters, and Schema.

springdoc.swagger-ui.url

String.To configure, the path of a custom OpenAPI file . Will be ignored if urls is used.

springdoc.swagger-ui.showCommonExtensions

false

Boolean. Controls the display of extensions (pattern, maxLength, minLength, maximum, minimum) fields and values for Parameters.

springdoc.swagger-ui.supportedSubmitMethods

Array=[get, put, post, delete, options, head, patch, trace]. List of HTTP methods that have the "Try it out" feature enabled. An empty array disables "Try it out" for all operations. This does not filter the operations from the display.

springdoc.swagger-ui.queryConfigEnabled

false

Boolean. Disabled since v1.6.0. This parameter enables (legacy) overriding configuration parameters via URL search params. See security advisory before enabling this feature.

springdoc.swagger-ui.oauth. additionalQueryStringParams

String. Additional query parameters added to authorizationUrl and tokenUrl.

springdoc.swagger-ui.disable-swagger-default-url

false

Boolean. To disable the swagger-ui default petstore url. (Available since v1.4.1).

springdoc.swagger-ui.urls[0].url

URL. The url of the swagger group, used by Topbar plugin. URLs must be unique among all items in this array, since they’re used as identifiers.

springdoc.swagger-ui.urls[0].name

String. The name of the swagger group, used by Topbar plugin. Names must be unique among all items in this array, since they’re used as identifiers.

springdoc.swagger-ui.urlsPrimaryName

String. The name of the swagger group which will be displayed when Swagger UI loads.

springdoc.swagger-ui.oauth.clientId

String. Default clientId. MUST be a string.

springdoc.swagger-ui.oauth.clientSecret

String. Default clientSecret. Never use this parameter in your production environment. It exposes crucial security information. This feature is intended for dev/test environments only.

springdoc.swagger-ui.oauth.realm

String. realm query parameter (for OAuth 1) added to authorizationUrl and tokenUrl.

springdoc.swagger-ui.oauth.appName

String. OAuth application name, displayed in authorization popup.

springdoc.swagger-ui.oauth.scopeSeparator

String. OAuth scope separator for passing scopes, encoded before calling, default value is a space (encoded value %20).

springdoc.swagger-ui.csrf.enabled

false

Boolean. To enable CSRF support

springdoc.swagger-ui.csrf.use-local-storage

false

Boolean. To get the CSRF token from the Local Storage.

springdoc.swagger-ui.csrf.use-session-storage

false

Boolean. To get the CSRF token from the Session Storage.

springdoc.swagger-ui.csrf.cookie-name

XSRF-TOKEN

String. Optional CSRF, to set the CSRF cookie name.

springdoc.swagger-ui.csrf.header-name

X-XSRF-TOKEN

String. Optional CSRF, to set the CSRF header name.

springdoc.swagger-ui.syntaxHighlight.activated

true

Boolean. Whether syntax highlighting should be activated or not.

springdoc.swagger-ui.syntaxHighlight.theme

agate

String. String=["agate"*, "arta", "monokai", "nord", "obsidian", "tomorrow-night"]. Highlight.js syntax coloring theme to use. (Only these 6 styles are available.)

springdoc.swagger-ui.oauth. useBasicAuthentication WithAccessCodeGrant

false

Boolean. Only activated for the accessCode flow. During the authorization_code request to the tokenUrl, pass the Client Password using the HTTP Basic Authentication scheme (Authorization header with Basic base64encode(client_id + client_secret)).

springdoc.swagger-ui.oauth. usePkceWithAuthorization CodeGrant

false

Boolean.Only applies to authorizatonCode flows. Proof Key for Code Exchange brings enhanced security for OAuth public clients.

springdoc.swagger-ui.persistAuthorization

false

Boolean. If set to true, it persists authorization data and it would not be lost on browser close/refresh

springdoc.swagger-ui.use-root-path

false

Boolean. If set to true, the swagger-ui will be accessible from the application root path directly.

+ + + +
+
+
+
+

6. Springdoc-openapi Plugins

+
+
+

6.1. Maven plugin

+
+

The aim of springdoc-openapi-maven-plugin is to generate json and yaml OpenAPI description during build time. +The plugin works during integration-tests phase, and generate the OpenAPI description. +The plugin works in conjunction with spring-boot-maven plugin.

+
+
+

You can test it during the integration tests phase using the maven command:

+
+
+
+
mvn verify
+
+
+
+

In order to use this functionality, you need to add the plugin declaration on the plugins section of your pom.xml:

+
+
+
+
<plugin>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-maven-plugin</artifactId>
+    <version>${spring-boot-maven-plugin.version}</version>
+    <configuration>
+        <jvmArguments>-Dspring.application.admin.enabled=true</jvmArguments>
+    </configuration>
+    <executions>
+        <execution>
+            <goals>
+                <goal>start</goal>
+                <goal>stop</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+<plugin>
+    <groupId>org.springdoc</groupId>
+    <artifactId>springdoc-openapi-maven-plugin</artifactId>
+    <version>1.5</version>
+    <executions>
+        <execution>
+            <id>integration-test</id>
+            <goals>
+                <goal>generate</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

For more custom settings of the springdoc-openapi-maven-plugin, you can consult the plugin documentation:

+
+ +
+
+

6.2. Gradle plugin

+
+

This plugin allows you to generate an OpenAPI 3 specification for a Spring Boot application from a Gradle build.

+
+
+
+
plugins {
+      id("org.springframework.boot") version "3.1.2"
+      id("org.springdoc.openapi-gradle-plugin") version "1.9.0"
+}
+
+
+
+
+

When you add this plugin and its runtime dependency plugins to your build file, the plugin creates the following tasks:

+
+
+
    +
  • +

    forkedSpringBootRun

    +
  • +
  • +

    generateOpenApiDocs

    +
  • +
+
+
+
+
gradle clean generateOpenApiDocs
+
+
+
+

For more custom configuration of springdoc-openapi-gradle-plugin ,you can consult the plugin documentation:

+
+ +
+
+
+
+

7. Springdoc-openapi Demos

+ +
+
+

8. Migrating from springdoc-openapi v1

+
+
+

All the modules have been renamed. +springdoc-openapi-starter-common integrates many spring modules support in order to hide the maximum of complexity. +It allows the support out of the box for Actuator / Spring Cloud Function / Spring Data Rest/ Spring Native/ Spring Hateoas / Spring Securtiy / Kotlin/ Javadoc.

+
+
+

The following table describes the main modules changes:

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
springdoc-openapi-v1springdoc-openapi-v2Description

springdoc-openapi-common

springdoc-openapi-starter-common

Includes foundation springdoc-openapi features

springdoc-openapi-data-rest

springdoc-openapi-starter-common

For Spring Data Rest support

springdoc-openapi-groovy

springdoc-openapi-starter-common

For Groovy support

springdoc-openapi-hateoas

springdoc-openapi-starter-common

For Spring Hateoas support

springdoc-openapi-javadoc

springdoc-openapi-starter-common

For Javadoc support

springdoc-openapi-kotlin

springdoc-openapi-starter-common

For Kotlin support

springdoc-openapi-security

springdoc-openapi-starter-common

For Spring Security support

springdoc-openapi-webmvc-core

springdoc-openapi-starter-webmvc-api

For Spring WebMvc support

springdoc-openapi-webflux-core

springdoc-openapi-starter-webflux-api

For Spring WebFlux support

springdoc-openapi-ui

springdoc-openapi-starter-webmvc-ui

For using the Swagger-UI in a Spring WebMvc context

springdoc-openapi-webflux-ui

springdoc-openapi-starter-webflux-ui

For using the Swagger-UI in a Spring WebFlux context

+
+ + + + + +
+ + +classes/annotations changes +
+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
springdoc-openapi-v1springdoc-openapi-v2

org.springdoc.core.SpringDocUtils

org.springdoc.core.utils.SpringDocUtils

org.springdoc.api.annotations.ParameterObject

org.springdoc.core.annotations.ParameterObject

org.springdoc.core.GroupedOpenApi

org.springdoc.core.models.GroupedOpenApi

org.springdoc.core.customizers.OpenApiCustomiser

org.springdoc.core.customizers.OpenApiCustomizer

org.springdoc.core.Constants

org.springdoc.core.utils.Constants

org.springdoc.core.SwaggerUiConfigParameters

org.springdoc.core.properties.SwaggerUiConfigParameters

+
+ + + + + +
+ + +Migration tips +
+
+
+

The following modules are not anymore needed and can be removed:

+
+
+
    +
  • +

    springdoc-openapi-javadoc

    +
  • +
  • +

    springdoc-openapi-kotlin

    +
  • +
  • +

    springdoc-openapi-data-rest

    +
  • +
  • +

    springdoc-openapi-security

    +
  • +
  • +

    springdoc-openapi-webmvc-core

    +
  • +
  • +

    springdoc-openapi-webflux-core

    +
  • +
  • +

    springdoc-openapi-hateoas

    +
  • +
  • +

    springdoc-openapi-groovy

    +
  • +
+
+
+

In addition:

+
+
+
    +
  • +

    Replace springdoc-openapi-ui by springdoc-openapi-starter-webmvc-ui

    +
  • +
  • +

    Replace springdoc-openapi-webflux-ui by springdoc-openapi-starter-webflux-ui

    +
  • +
+
+
+
+
+

9. Migrating from SpringFox

+
+
+
    +
  • +

    Remove springfox and swagger 2 dependencies. Add springdoc-openapi-starter-webmvc-ui dependency instead.

    +
  • +
+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+      <version>2.8.9</version>
+   </dependency>
+
+
+
+
    +
  • +

    Replace swagger 2 annotations with swagger 3 annotations (it is already included with springdoc-openapi-starter-webmvc-ui dependency). +Package for swagger 3 annotations is io.swagger.v3.oas.annotations.

    +
    +
      +
    • +

      @Api@Tag

      +
    • +
    • +

      @ApiIgnore@Parameter(hidden = true) or @Operation(hidden = true) or @Hidden

      +
    • +
    • +

      @ApiImplicitParam@Parameter

      +
    • +
    • +

      @ApiImplicitParams@Parameters

      +
    • +
    • +

      @ApiModel@Schema

      +
    • +
    • +

      @ApiModelProperty(allowEmptyValue = true)@Schema(nullable = true)

      +
    • +
    • +

      @ApiModelProperty@Schema

      +
    • +
    • +

      @ApiOperation(value = "foo", notes = "bar")@Operation(summary = "foo", description = "bar")

      +
    • +
    • +

      @ApiParam@Parameter

      +
    • +
    • +

      @ApiResponse(code = 404, message = "foo")@ApiResponse(responseCode = "404", description = "foo")

      +
    • +
    +
    +
  • +
  • +

    This step is optional: Only if you have multiple Docket beans replace them with GroupedOpenApi beans.

    +
  • +
+
+
+

Before:

+
+
+
+
  @Bean
+  public Docket publicApi() {
+      return new Docket(DocumentationType.SWAGGER_2)
+              .select()
+              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public"))
+              .paths(PathSelectors.regex("/public.*"))
+              .build()
+              .groupName("springshop-public")
+              .apiInfo(apiInfo());
+  }
+
+  @Bean
+  public Docket adminApi() {
+      return new Docket(DocumentationType.SWAGGER_2)
+              .select()
+              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin"))
+              .paths(PathSelectors.regex("/admin.*"))
+              .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class))
+              .build()
+              .groupName("springshop-admin")
+              .apiInfo(apiInfo());
+  }
+
+
+
+
+

Now:

+
+
+
+
  @Bean
+  public GroupedOpenApi publicApi() {
+      return GroupedOpenApi.builder()
+              .group("springshop-public")
+              .pathsToMatch("/public/**")
+              .build();
+  }
+  @Bean
+  public GroupedOpenApi adminApi() {
+      return GroupedOpenApi.builder()
+              .group("springshop-admin")
+              .pathsToMatch("/admin/**")
+              .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class))
+              .build();
+  }
+
+
+
+
+

If you have only one Docket — remove it and instead add properties to your application.properties:

+
+
+
+
springdoc.packagesToScan=package1, package2
+springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
    +
  • +

    Add bean of OpenAPI type. See example:

    +
  • +
+
+
+
+
  @Bean
+  public OpenAPI springShopOpenAPI() {
+      return new OpenAPI()
+              .info(new Info().title("SpringShop API")
+              .description("Spring shop sample application")
+              .version("v0.0.1")
+              .license(new License().name("Apache 2.0").url("http://springdoc.org")))
+              .externalDocs(new ExternalDocumentation()
+              .description("SpringShop Wiki Documentation")
+              .url("https://springshop.wiki.github.org/docs"));
+  }
+
+
+
+
+ +
+
+
+
+

10. Other resources

+
+
+

10.1. Additional resources to get started

+ +
+
+

10.2. Dependencies repository

+
+

The springdoc-openapi libraries are hosted on maven central repository. +The artifacts can be viewed accessed at the following locations:

+
+
+

Releases:

+
+ +
+

Snapshots:

+
+ +
+
+
+
+ +
+
+

springdoc-openapi is on Open Collective.

+
+
+

If you ❤️ this project consider becoming a sponsor.

+
+
+

This money is used to cover project expenses and your donation will help the project live and grow successfully.

+
+
+

Thank you to our bronze sponsors!

+
+

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

+
+

11.1. Benefits of being a bronze sponsor

+
+

Bronze sponsors donate $50 per month to the project, and get the following benefits:

+
+
+
    +
  • +

    You will receive a Sponsor badge 🎖!. Visibility on the front page of springdoc.org in the welcome page (about 55,000 views/month on May, 2022).

    +
  • +
  • +

    “Thank you” tweet from `springdoc team'.

    +
  • +
+
+
+
+

11.2. Benefits of being a silver sponsor

+
+

Silver sponsors donate $100 per month to the project, and get the following benefits:

+
+
+
    +
  • +

    Same benefits as bronze sponsors (visibility on main pages, and thank you tweet).

    +
  • +
  • +

    The ability to get support for 2 issues every month, non transferable.

    +
  • +
  • +

    If issues are not created by the end of the month, it is lost

    +
  • +
+
+
+
+

11.3. Benefits of being a gold sponsor

+
+

Gold sponsors donate $500 per month to the project, and get the following benefits:

+
+
+
    +
  • +

    Same benefits as silver sponsors (visibility on main pages, and thank you tweet).

    +
  • +
  • +

    The ability to get support for 10 issues every month, non transferable.

    +
  • +
  • +

    Company logos on all springdoc.org page footers

    +
  • +
  • +

    If issues are not created by the end of the month, the remaining ones are lost.

    +
  • +
+
+
+
+
+
+

12. Special Thanks

+
+
+
    +
  • +

    Thank you to The Spring Team for sharing all relevant resources around Spring projects.

    +
  • +
  • +

    Thanks a lot JetBrains for supporting springdoc-openapi project.

    +
  • +
+
+
+
+JetBrains logo +
+
+
+
+
+

13. F.A.Q

+
+
+

13.1. How can I define multiple OpenAPI definitions in one Spring Boot project?

+
+

You can define your own groups of API based on the combination of: API paths and packages to scan. Each group should have a unique groupName. +The OpenAPI description of this group, will be available by default on:

+
+
+
    +
  • +

    http://server:port/context-path/v3/api-docs/groupName

    +
  • +
+
+
+

To enable the support of multiple OpenAPI definitions, a bean of type GroupedOpenApi needs to be defined.

+
+
+

For the following Group definition(based on package path), the OpenAPI description URL will be : /v3/api-docs/stores

+
+
+
+
@Bean
+public GroupedOpenApi storeOpenApi() {
+   String paths[] = {"/store/**"};
+   return GroupedOpenApi.builder().group("stores").pathsToMatch(paths)
+         .build();
+}
+
+
+
+
+

For the following Group definition (based on package name), the OpenAPI description URL will be: /v3/api-docs/users

+
+
+
+
@Bean
+public GroupedOpenApi userOpenApi() {
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"};
+   return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan)
+         .build();
+}
+
+
+
+
+

For the following Group definition(based on path), the OpenAPI description URL will be: /v3/api-docs/pets

+
+
+
+
@Bean
+public GroupedOpenApi petOpenApi() {
+   String paths[] = {"/pet/**"};
+   return GroupedOpenApi.builder().group("pets").pathsToMatch(paths)
+         .build();
+}
+
+
+
+
+

For the following Group definition (based on package name and path), the OpenAPI description URL will be: /v3/api-docs/groups

+
+
+
+
@Bean
+public GroupedOpenApi groupOpenApi() {
+   String paths[] = {"/v1/**"};
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"};
+   return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
+         .build();
+}
+
+
+
+
+

For more details about the usage, you can have a look at the following sample Test:

+
+ +
+
+

13.2. How can I configure Swagger UI?

+
+
    +
  • +

    The support of the swagger official properties is available on springdoc-openapi. See Official documentation.

    +
  • +
  • +

    You can use the same swagger properties in the documentation as Spring Boot properties.

    +
  • +
+
+
+ + + + + +
+ + +All these properties should be declared with the following prefix: springdoc.swagger-ui +
+
+
+
+

13.3. How can I filter the resources documented in the output specification by the provided group?

+
+
    +
  • +

    You can use the standard swagger-ui property filter.

    +
  • +
+
+
+
+
springdoc.swagger-ui.filter=group-a
+
+
+
+
+

13.4. How can I disable/enable Swagger UI generation based on env variable?

+
+
    +
  • +

    This property helps you disable only the UI.

    +
  • +
+
+
+
+
springdoc.swagger-ui.enabled=false
+
+
+
+
+

13.5. How can I control the default expansion setting for the operations and tags, in the Swagger UI ,

+
+
    +
  • +

    You can set this property in your application.yml like so for example:

    +
  • +
+
+
+
+
springdoc.swagger-ui.doc-expansion= none
+
+
+
+
+

13.6. How can I change the layout of the swagger-ui?

+
+
    +
  • +

    For layout options, you can use swagger-ui configuration options. For example:

    +
  • +
+
+
+
+
springdoc.swagger-ui.layout=BaseLayout
+
+
+
+
+

13.7. How can I sort endpoints alphabetically?

+
+
    +
  • +

    You can use the following springdoc-openapi properties:

    +
  • +
+
+
+
+
#For sorting endpoints alphabetically
+springdoc.swagger-ui.operationsSorter=alpha
+#For sorting tags alphabetically
+springdoc.swagger-ui.tagsSorter=alpha
+
+
+
+
+

13.8. How can I disable the try it out button?

+
+
    +
  • +

    You have to set the following property:

    +
  • +
+
+
+
+
springdoc.swagger-ui.supportedSubmitMethods=get, put, post, delete, options, head, patch, trace
+
+
+
+
+

13.9. How can I add Reusable Enums ?

+
+
    +
  • +

    You should add @Schema(enumAsRef = true) on your enum.

    +
  • +
+
+
+
+

13.10. How can i apply enumAsRef = true to all enums ?

+
+
    +
  • +

    Declare the following property:

    +
  • +
+
+
+
+
static {
+    io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true;
+}
+
+
+
+
+

13.11. How can I explicitly set which paths to filter?

+
+
    +
  • +

    You can set list of paths to include using the following property:

    +
  • +
+
+
+
+
springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
+

13.12. How can I explicitly set which packages to scan?

+
+
    +
  • +

    You can set list of packages to include using the following property:

    +
  • +
+
+
+
+
springdoc.packagesToScan=package1, package2
+
+
+
+
+

13.13. How can I set Swagger properties programmatically?

+
+

These can be set by creating a swaggerUiConfig bean as follows:

+
+
+
+
@Bean
+@Primary
+fun swaggerUiConfig(config: SwaggerUiConfigProperties): SwaggerUiConfigProperties {
+    config.showCommonExtensions = true
+    config.queryConfigEnabled = true
+    return config
+}
+
+
+
+
+
+

13.14. How can I ignore some field of model ?

+
+
    +
  • +

    You can use the following annotation on the top of the field that you want to hide:

    +
  • +
  • +

    @Schema(hidden = true)

    +
  • +
+
+
+
+

13.15. How can I ignore @AuthenticationPrincipal parameter from spring-security ?

+
+
    +
  • +

    A solution workaround would be to use: @Parameter(hidden = true)

    +
  • +
  • +

    The projects that use spring-boot-starter-security or spring-security-oauth2-authorization-server should use:

    +
    +
      +
    • +

      springdoc-openapi-starter-webmvc-api if they depend on spring-boot-starter-web and they only need the access to the OpenAPI endpoints.

      +
    • +
    • +

      OR springdoc-openapi-starter-webmvc-ui, if they depend on spring-boot-starter-web and they also need the access to the swagger-ui.

      +
    • +
    • +

      OR springdoc-openapi-starter-webflux-api if they depend on spring-boot-starter-webflux and they only the access to the OpenAPI endpoints.

      +
    • +
    • +

      OR springdoc-openapi-starter-webflux-ui, if they depend on spring-boot-starter-webflux and they also need the access to the swagger-ui.

      +
    • +
    +
    +
  • +
+
+
+
+

13.16. Is there a Gradle plugin available?

+
+
    +
  • +

    Yes. More details are available, in the gradle plugin section.

    +
  • +
+
+
+
+

13.17. How can I hide a parameter from the documentation ?

+
+
    +
  • +

    You can use @Parameter(hidden = true)

    +
  • +
+
+
+
+

13.18. Is @Parameters annotation supported ?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

13.19. Does springdoc-openapi support Jersey?

+
+ +
+
+
+

13.20. Can springdoc-openapi generate API only for @RestController?

+
+
    +
  • +

    @RestController is equivalent to @Controller + @RequestMapping on the type level.

    +
  • +
  • +

    For some legacy apps, we are constrained to still support both.

    +
  • +
  • +

    If you need to hide the @Controller on the type level, in this case, you can use: @Hidden on controller level.

    +
  • +
  • +

    Please note this annotation can be also used to hide some methods from the generated documentation.

    +
  • +
+
+
+
+

13.21. Are the following validation annotations supported : @NotEmpty @NotBlank @PositiveOrZero @NegativeOrZero?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

13.22. How can I map Pageable (spring-data-commons) object to correct URL-Parameter in Swagger UI?

+
+

The support for Pageable of spring-data-commons is available out-of-the box since springdoc-openapi v1.6.0. +For this, you have to combine @ParameterObject annotation with the Pageable type.

+
+
+

Before springdoc-openapi v1.6.0:

+
+
+
    +
  • +

    You can use as well @ParameterObject instead of @PageableAsQueryParam for HTTP GET methods.

    +
  • +
+
+
+
+
static {
+    getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
+            .replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
+}
+
+
+
+
+
    +
  • +

    Another solution, is to configure Pageable manually:

    +
    +
      +
    • +

      you will have to declare the explicit mapping of Pageable fields as Query Params and add the @Parameter(hidden = true) Pageable pageable on your pageable parameter.

      +
    • +
    • +

      You should also, declare the annotation @PageableAsQueryParam provided by springdoc-openapi on the method level, or declare your own if need to define your custom description, defaultValue, …​

      +
    • +
    +
    +
  • +
+
+
+

If you want to disable the support of spring Pageable Type, you can use:

+
+
+
+
springdoc.model-converters.pageable-converter.enabled=false
+
+
+
+ + + + + +
+ + +The property springdoc.model-converters.pageable-converter.enabled is only available since v1.5.11+ +
+
+
+
+

13.23. How can I generate enums in the generated description?

+
+
    +
  • +

    You could add a property allowableValues, to @Parameter. For example:

    +
  • +
+
+
+
+
@GetMapping("/example")
+public Object example(@Parameter(name ="json", schema = @Schema(description = "var 1",type = "string", allowableValues = {"1", "2"}))
+String json) {
+   return null;
+}
+
+
+
+
+
    +
  • +

    or you could override toString on your enum:

    +
  • +
+
+
+
+
@Override
+@JsonValue
+public String toString() {
+   return String.valueOf(action);
+}
+
+
+
+
+
+

13.24. How can I deploy springdoc-openapi-starter-webmvc-ui behind a reverse proxy?

+
+
    +
  • +

    If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…​) might change along the way. Your application may be running on 10.10.10.10:8080, but HTTP clients should only see example.org.

    +
  • +
  • +

    RFC7239 "Forwarded Headers" defines the Forwarded HTTP header; proxies can use this header to provide information about the original request. You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages. There are also non-standard headers, like X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, and X-Forwarded-Prefix.

    +
  • +
  • +

    If the proxy adds the commonly used X-Forwarded-For and X-Forwarded-Proto headers, setting server.forward-headers-strategy to NATIVE is enough to support those. With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior.

    +
  • +
  • +

    You need to make sure the following header is set in your reverse proxy configuration: X-Forwarded-Prefix

    +
  • +
  • +

    For example, using Apache 2, configuration:

    +
  • +
+
+
+
+
RequestHeader set X-Forwarded-Prefix "/custom-path"
+
+
+
+
    +
  • +

    Then, in your Spring Boot application make sure your application handles this header: X-Forwarded-For. There are two ways to achieve this:

    +
  • +
+
+
+
+
server.use-forward-headers=true
+
+
+
+
    +
  • +

    If this is not enough, Spring Framework provides a ForwardedHeaderFilter. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK.

    +
  • +
  • +

    Since Spring Boot 2.2, this is the new property to handle reverse proxy headers:

    +
  • +
+
+
+
+
server.forward-headers-strategy=framework
+
+
+
+
    +
  • +

    And you can add the following bean to your application:

    +
  • +
+
+
+
+
@Bean
+ForwardedHeaderFilter forwardedHeaderFilter() {
+   return new ForwardedHeaderFilter();
+}
+
+
+
+
+
    +
  • +

    If you need to manually adjust the URL displayed in the Swagger UI, implement the ServerBaseUrlCustomizer interface. This might be necessary to remove the port number, for example.

    +
  • +
+
+
+
+
@Bean
+public class CustomServerBaseUrlCustomizer implements ServerBaseUrlCustomizer {
+    @Override
+    public String customize(String serverBaseUrl) {
+        try {
+            URL url = new URL(serverBaseUrl);
+            if (url.getHost().contains(".com")) {
+                serverBaseUrl = new URL(url.getProtocol(),url.getHost(),url.getFile()).toString();
+            }
+        } catch (MalformedURLException ex) {
+            // nothing we can do
+        }
+
+        return serverBaseUrl;
+    }
+}
+
+
+
+
+
+

13.25. Is @JsonView annotations in Spring MVC APIs supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

13.26. Adding springdoc-openapi-starter-webmvc-ui dependency breaks my public/index.html welcome page

+
+
    +
  • +

    If you already have static content on your root, and you don’t want it to be overridden by springdoc-openapi-starter-webmvc-ui configuration, you can just define a custom configuration of the swagger-ui, in order not to override the configuration of your files from in your context-root:

    +
  • +
  • +

    For example use:

    +
  • +
+
+
+
+
springdoc.swagger-ui.path= /swagger-ui/api-docs.html
+
+
+
+
+

13.27. How can I test the Swagger UI?

+ +
+
+

13.28. How can I customise the OpenAPI object ?

+
+ +
+
+
+
@Bean
+public OpenApiCustomizer consumerTypeHeaderOpenAPICustomizer() {
+return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
+    .forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myConsumerTypeHeader")));
+}
+
+
+
+
+ + + + + +
+ + +This bean OpenApiCustomizer will be applied to the Default OpenAPI only. +
+
+
+

If you need the OpenApiCustomizer to applied to GroupedOpenApi as well, then use GlobalOpenApiCustomizer instead.

+
+
+
+

13.29. How can I return an empty content as response?

+
+
    +
  • +

    It is be possible to handle as return an empty content as response using, one of the following syntaxes:

    +
  • +
  • +

    content = @Content

    +
  • +
  • +

    content = @Content(schema = @Schema(hidden = true))

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
@Operation(summary = "Get thing", responses = {
+      @ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
+      @ApiResponse(responseCode = "404", description = "Not found", content = @Content),
+      @ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) })
+@RequestMapping(path = "/testme", method = RequestMethod.GET)
+ResponseEntity<String> testme() {
+   return ResponseEntity.ok("Hello");
+}
+
+
+
+
+
+

13.30. How are endpoints with multiple consuming media types supported?

+
+
    +
  • +

    An overloaded method on the same class, with the same HTTP Method and path, will have as a result, only one OpenAPI Operation generated.

    +
  • +
  • +

    In addition, it’s recommended to have the @Operation in the level of one of the overloaded methods. Otherwise it might be overridden if it’s declared many times within the same overloaded method.

    +
  • +
+
+
+
+

13.31. How can I get yaml and json (OpenAPI) in compile time?

+
+ +
+
+
+

13.32. What are the ignored types in the documentation?

+
+ +
+
+
+

13.33. How can i disable ignored types:

+
+

If you don’t want to ignore the types Principal, Locale, HttpServletRequest, and others,:

+
+
+
+
SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class)
+
+
+
+
+
+

13.34. How do I add authorization header in requests?

+
+
    +
  • +

    You should add the @SecurityRequirement tags to your protected APIs.

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
@Operation(security = { @SecurityRequirement(name = "bearer-key") })
+
+
+
+
    +
  • +

    And the security definition sample:

    +
  • +
+
+
+
+
@Bean
+ public OpenAPI customOpenAPI() {
+   return new OpenAPI()
+          .components(new Components()
+          .addSecuritySchemes("bearer-key",
+          new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
+}
+
+
+
+
+
+

13.35. Differentiation to Springfox project

+
+
    +
  • +

    OAS 3 was released in July 2017, and there was no release of springfox to support OAS 3. +springfox covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately.

    +
  • +
  • +

    We decided to move forward and share the library that we already used on our internal projects, with the community.

    +
  • +
  • +

    The biggest difference with springfox, is that we integrate new features not covered by springfox:

    +
  • +
  • +

    The integration between Spring Boot and OpenAPI 3 standard.

    +
  • +
  • +

    We rely on on swagger-annotations and swagger-ui only official libraries.

    +
  • +
  • +

    We support new features on Spring 5, like spring-webflux with annotated and functional style.

    +
  • +
  • +

    We do our best to answer all the questions and address all issues or enhancement requests

    +
  • +
+
+
+
+

13.36. How do I migrate to OpenAPI 3 with springdoc-openapi

+
+
    +
  • +

    There is no relation between springdoc-openapi and springfox.If you want to migrate to OpenAPI 3:

    +
  • +
  • +

    Remove all the dependencies and the related code to springfox

    +
  • +
  • +

    Add springdoc-openapi-starter-webmvc-ui dependency

    +
  • +
  • +

    If you don’t want to serve the UI from your root path or there is a conflict with an existing configuration, you can just change the following property:

    +
  • +
+
+
+
+
springdoc.swagger-ui.path=/you-path/swagger-ui.html
+
+
+
+
+

13.37. How can I set a global header?

+
+
    +
  • +

    You may have global parameters with Standard OpenAPI description.

    +
  • +
  • +

    If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.

    +
  • +
  • +

    You can define common parameters under parameters in the global components section and reference them elsewhere via $ref. You can also define global header parameters.

    +
  • +
  • +

    For this, you can override to OpenAPI Bean, and set the global headers or parameters definition on the components level.

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+ return new OpenAPI()
+        .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
+        .addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
+        .info(new Info()
+        .title("Petstore API")
+        .version(appVersion)
+        .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
+        .termsOfService("http://swagger.io/terms/")
+        .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
+

13.38. Are Callbacks supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

13.39. How can I define SecurityScheme ?

+
+
    +
  • +

    You can use: @SecurityScheme annotation.

    +
  • +
  • +

    Or you can define it programmatically, by overriding OpenAPI Bean:

    +
  • +
+
+
+
+
 @Bean
+ public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+  return new OpenAPI()
+   .components(new Components().addSecuritySchemes("basicScheme",
+   new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+   info(new Info().title("SpringShop API").version(appVersion)
+   .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+ }
+
+
+
+
+
+

13.40. How can I hide an operation or a controller from documentation ?

+
+
    +
  • +

    You can use @io.swagger.v3.oas.annotations.Hidden annotation at @RestController, @RestControllerAdvice and method level

    +
  • +
  • +

    The @Hidden annotation on exception handler methods, is considered when building generic (error) responses from @ControllerAdvice exception handlers.

    +
  • +
  • +

    Or use: @Operation(hidden = true)

    +
  • +
+
+
+
+

13.41. How to configure global security schemes?

+
+
    +
  • +

    For global SecurityScheme, you can add it inside your own OpenAPI definition:

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI().components(new Components()
+    .addSecuritySchemes("basicScheme", new SecurityScheme()
+    .type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API")
+    .version("100")).addTagsItem(new Tag().name("mytag"));
+}
+
+
+
+
+
+

13.42. Can I use spring property with swagger annotations?

+
+
    +
  • +

    The support of spring property resolver for @Info: title * description * version * termsOfService

    +
  • +
  • +

    The support of spring property resolver for @Info.license: name * url

    +
  • +
  • +

    The support of spring property resolver for @Info.contact: name * email * url

    +
  • +
  • +

    The support of spring property resolver for @Operation: description * summary

    +
  • +
  • +

    The support of spring property resolver for @Parameter: description * name

    +
  • +
  • +

    The support of spring property resolver for @ApiResponse: description

    +
  • +
  • +

    Its also possible to declare security URLs for @OAuthFlow: openIdConnectUrl * authorizationUrl * refreshUrl * tokenUrl

    +
  • +
  • +

    The support of spring property resolver for @Schema: name * title * description , by setting springdoc.api-docs.resolve-schema-properties to true

    +
  • +
  • +

    The support of spring property resolver for @ExtensionProperty by setting springdoc.api-docs.resolve-extensions-properties to true

    +
  • +
+
+
+
+

13.43. How is server URL generated ?

+
+
    +
  • +

    Generating automatically server URL may be useful, if the documentation is not present.

    +
  • +
  • +

    If the server annotations are present, they will be used instead.

    +
  • +
+
+
+
+

13.44. How can I disable springdoc-openapi cache?

+
+
    +
  • +

    By default, the OpenAPI description is calculated once, and then cached.

    +
  • +
  • +

    Sometimes the same swagger-ui is served behind internal and external proxies. some users want the server URL, to be computed on each http request.

    +
  • +
  • +

    In order to disable springdoc cache, you will have to set the following property:

    +
  • +
+
+
+
+
springdoc.cache.disabled= true
+
+
+
+
+

13.45. How can I expose the mvc api-docs endpoints without using the swagger-ui?

+
+
    +
  • +

    You should use the springdoc-openapi-core dependency only:

    +
  • +
+
+
+
+
<dependency>
+  <groupId>org.springdoc</groupId>
+  <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
+  <version>latest.version</version>
+</dependency>
+
+
+
+
+

13.46. How can I disable springdoc-openapi endpoints ?

+
+
    +
  • +

    Use the following property:

    +
  • +
+
+
+
+
springdoc.api-docs.enabled=false
+
+
+
+
+

13.47. How can I hide Schema of the the response ?

+
+
    +
  • +

    To hide the response element, using @Schema annotation, as follows, at operation level:

    +
  • +
+
+
+
+
@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))))
+
+
+
+
    +
  • +

    Or directly at @ApiResponses level:

    +
  • +
+
+
+
+
@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) })
+OR
+@ApiResponse(responseCode = "404", description = "Not found", content = @Content)
+
+
+
+
+

13.48. What is the URL of the swagger-ui, when I set a different context-path?

+
+
    +
  • +

    If you use different context-path:

    +
  • +
+
+
+
+
server.servlet.context-path= /foo
+
+
+
+
    +
  • +

    The swagger-ui will be available on the following URL:

    +
    +
      +
    • +

      http://server:port/foo/swagger-ui.html

      +
    • +
    +
    +
  • +
+
+
+
+

13.49. Can I customize OpenAPI object programmatically?

+
+
    +
  • +

    You can Define your own OpenAPI Bean: If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+   return new OpenAPI()
+    .components(new Components().addSecuritySchemes("basicScheme",
+            new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+    .info(new Info().title("SpringShop API").version(appVersion)
+            .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
    +
  • +

    If you need the definitions to appear within a specific group, and respect the conditions specified on the GroupedOpenApi, you can add OpenApiCustomizer to your GroupedOpenApi definition.

    +
  • +
+
+
+
+
GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomizer(customerGlobalHeaderOpenApiCustomizer())
+                .build()
+
+@Bean
+public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() {
+   return openApi -> openApi.path("/foo",
+   new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses()
+   .addApiResponse("default",new ApiResponse().description("")
+   .content(new Content().addMediaType("fatz", new MediaType()))))));
+}
+
+
+
+
+
+

13.50. Where can I find the source code of the demo applications?

+
+ +
+
+
+

13.51. Does this library supports annotations from interfaces?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

13.52. What is the list of the excluded parameter types?

+ +
+
+

13.53. Is file upload supported ?

+
+
    +
  • +

    The library supports the main file types: MultipartFile, @RequestPart, FilePart

    +
  • +
  • +

    You can upload a file as follows:

    +
  • +
+
+
+
+
import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Encoding;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+
+@PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+public ResponseEntity<?> upload(@Parameter(description = "file") final MultipartFile file) {
+    return null;
+}
+
+@PostMapping(value = "/uploadFileWithQuery", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+public ResponseEntity<?> uploadFileWithQuery(@Parameter(description = "file") @RequestPart("file") final MultipartFile file,
+        @Parameter(description = "An extra query parameter") @RequestParam String name) {
+    return null;
+}
+
+@PostMapping(value = "/uploadFileWithJson", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {
+        MediaType.APPLICATION_JSON_VALUE})
+public ResponseEntity<?> uploadFileWithJson(
+        @RequestBody(content = @Content(encoding = @Encoding(name = "jsonRequest", contentType = MediaType.APPLICATION_JSON_VALUE)))
+        @Parameter(description = "An extra JSON payload sent with file") @RequestPart("jsonRequest") final JsonRequest jsonRequest,
+        @RequestPart("file") final MultipartFile file) {
+    return null;
+}
+
+
+
+
+
+

13.54. Can I use @Parameter inside @Operation annotation?

+
+
    +
  • +

    Yes, it’s supported

    +
  • +
+
+
+
+

13.55. Why my parameter is marked as required?

+
+
    +
  • +

    Any @GetMapping parameters is marked as required, even if @RequestParam is missing.

    +
  • +
  • +

    You can add @Parameter(required=false) annotation if you need different behaviour.

    +
  • +
  • +

    Query parameters with defaultValue specified are marked as required.

    +
  • +
+
+
+
+

13.56. How are overloaded methods with the same endpoints, but with different parameters

+
+
    +
  • +

    springdoc-openapi renders these methods as a single endpoint. It detects the overloaded endpoints, and generates parameters.schema.oneOf.

    +
  • +
+
+
+
+

13.57. What is a proper way to set up Swagger UI to use provided spec.yml?

+
+
    +
  • +

    With this property, all the springdoc-openapi auto-configuration beans are disabled:

    +
  • +
+
+
+
+
springdoc.api-docs.enabled=false
+
+
+
+
    +
  • +

    Then enable the minimal Beans configuration, by adding this Bean:

    +
  • +
+
+
+
+
@Bean
+SpringDocConfiguration springDocConfiguration(){
+   return new SpringDocConfiguration();
+}
+
+@Bean
+SpringDocConfigProperties springDocConfigProperties() {
+   return new SpringDocConfigProperties();
+}
+
+@Bean
+ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){
+    return new ObjectMapperProvider(springDocConfigProperties);
+}
+
+
+
+
+
    +
  • +

    Then configure, the path of your custom UI yaml file.

    +
  • +
+
+
+
+
springdoc.swagger-ui.url=/api-docs.yaml
+
+
+
+
+

13.58. Is there a way to send authorization header through the @Parameter tag?

+
+ +
+
+
+

13.59. My Rest Controller using @Controller annotation is ignored?

+
+
    +
  • +

    This is the default behaviour if your @Controller doesn’t have annotation @ResponseBody

    +
  • +
  • +

    You can change your controllers to @RestControllers. Or add @ResponseBody + @Controller.

    +
  • +
  • +

    If its not possible, you can configure springdoc to scan you additional controller using SpringDocUtils. For example:

    +
  • +
+
+
+
+
static {
+   SpringDocUtils.getConfig().addRestControllers(HelloController.class);
+}
+
+
+
+
+
+

13.60. How can I define groups using application.yml?

+
+
    +
  • +

    You can load groups dynamically using spring-boot configuration files.

    +
  • +
  • +

    Note that, for this usage, you don’t have to declare the GroupedOpenApi Bean.

    +
  • +
  • +

    You need to declare the following properties, under the prefix springdoc.group-configs.

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
springdoc.group-configs[0].group=users
+springdoc.group-configs[0].paths-to-match=/user/**
+springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api
+
+
+
+ +
+
+
+

13.61. How can I extract fields from parameter object ?

+
+
    +
  • +

    You can use springdoc annotation @ParameterObject.

    +
  • +
  • +

    Request parameter annotated with @ParameterObject will help adding each field of the parameter as a separate request parameter.

    +
  • +
  • +

    This is compatible with Spring MVC request parameters mapping to POJO object.

    +
  • +
  • +

    This annotation does not support nested parameter objects.

    +
  • +
  • +

    POJO object must contain getters for fields with mandatory prefix get. Otherwise, the swagger documentation will not show the fields of the annotated entity.

    +
  • +
+
+
+
+

13.62. How can I use the last springdoc-openapi SNAPSHOT ?

+
+
    +
  • +

    For testing purposes only, you can test temporarily using the last springdoc-openapi SNAPSHOT

    +
  • +
  • +

    To achieve that, configure your pom.xml file with the following <repositories> section:

    +
  • +
+
+
+
+
    <repositories>
+      <repository>
+        <name>Central Portal Snapshots</name>
+        <id>central-portal-snapshots</id>
+        <url>https://central.sonatype.com/repository/maven-snapshots/</url>
+        <releases>
+          <enabled>false</enabled>
+        </releases>
+        <snapshots>
+          <enabled>true</enabled>
+        </snapshots>
+      </repository>
+    </repositories>
+
+
+
+
+

13.63. How can I use enable springdoc-openapi MonetaryAmount support ?

+
+
    +
  • +

    If an application wants to enable the springdoc-openapi support, it declares:

    +
  • +
+
+
+
+
SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
+
+
+
+
+
    +
  • +

    Another solution, without using springdoc-openapi MonetaryAmount, would be:

    +
  • +
+
+
+
+
SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema()
+            .addProperties("amount", new NumberSchema()).example(99.96)
+            .addProperties("currency", new StringSchema().example("USD")));
+
+
+
+
+
+

13.64. How can i aggregate external endpoints (exposing OPENAPI 3 spec) inside one single application?

+
+

The properties springdoc.swagger-ui.urls.*, are suitable to configure external (/v3/api-docs url). +For example if you want to agreagte all the endpoints of other services, inside one single application. +IMPORTANT: Don’t forget that CORS needs to be enabled as well.

+
+
+
+

13.65. How can use custom json/yml file instead of generated one ?

+
+

If your file open-api.json, contains the OpenAPI documentation in OpenAPI 3 format. +Then simply declare: The file name can be anything you want, from the moment your declaration is consistent yaml or json OpenAPI Spec.

+
+
+
+
   springdoc.swagger-ui.url=/open-api.json
+
+
+
+

Then the file open-api.json, should be located in: src/main/resources/static +No additional configuration is needed.

+
+
+
+

13.66. How can i enable CSRF support?

+
+

If you are using standard headers.( For example using spring-security headers) +If the CSRF Token is required, swagger-ui automatically sends the new XSRF-TOKEN during each HTTP REQUEST.

+
+
+

If your XSRF-TOKEN isn’t standards-based, you can use a requestInterceptor to manually capture and attach the latest xsrf token to requests programmatically via spring resource transformer:

+
+ +
+

Starting from release v1.4.4 of springdoc-openapi, a new property is added to enable CSRF support, while using standard header names:

+
+
+
+
springdoc.swagger-ui.csrf.enabled=true
+
+
+
+
+

13.67. How can i disable the default swagger petstore URL?

+
+

You can use the following property:

+
+
+
+
springdoc.swagger-ui.disable-swagger-default-url=true
+
+
+
+
+

13.68. Is @PageableDefault supported, to enhance the OpenAPI 3 docuementation?

+
+

Yes, you can use it in conjunction with @ParameterObject annotation. +Also, the spring-boot spring.data.web. and spring.data.rest.default. properties are supported since v1.4.5

+
+
+
+

13.69. How can i make spring security login-endpoint visible ?

+
+

You can use the following property:

+
+
+
+
springdoc.show-login-endpoint=true
+
+
+
+
+

13.70. How can i show schema definitions even the schema is not referenced?

+
+

You can use the following property:

+
+
+
+
springdoc.remove-broken-reference-definitions=false
+
+
+
+
+

13.71. How to override @Deprecated?

+
+

The whole idea of springdoc-openapi is to get your documentation the closest to the code, with minimal code changes. +If the code contains @Deprecated, sprindoc-openapi will consider its schema as Deprecated as well. +If you want to declare a field on swagger as non deprecated, even with the java code, the field contains @Depreacted, +You can use the following property that is available since release v1.4.3:

+
+
+
+
springdoc.model-converters.deprecating-converter.enabled=false
+
+
+
+
+

13.72. How can i display a method that returns ModelAndView?

+
+

You can use the following property:

+
+
+
+
springdoc.model-and-view-allowed=true
+
+
+
+
+

13.73. How can i have pretty-printed output of the OpenApi specification?

+
+

You can use the following property:

+
+
+
+
springdoc.writer-with-default-pretty-printer=true
+
+
+
+
+

13.74. How can i define different schemas for the same class?

+
+

Complex objects are always resolved as a reference to a schema defined in components. +For example let’s consider a Instance class with an workAddress and homeAddress attribute of type Address:

+
+
+
+
public class PersonDTO {
+
+    @JsonProperty
+    private String email;
+
+    @JsonProperty
+    private String firstName;
+
+    @JsonProperty
+    private String lastName;
+
+    @Schema(ref = "WorkAddressSchema")
+    @JsonProperty
+    private Address workAddress;
+
+    @Schema(ref = "HomeAddressSchema")
+    @JsonProperty
+    private Address homeAddress;
+
+}
+
+public class Address {
+
+    @JsonProperty
+    private String addressName;
+
+}
+
+
+
+
+

If you want to define two different schemas for this class, you can set up 2 different schemas as follow:

+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+return new OpenAPI().components(new Components()
+.addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address" ))
+.addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address" )));
+}
+
+private Schema getSchemaWithDifferentDescription(Class className, String description){
+ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+.resolveAsResolvedSchema(
+new AnnotatedType(className).resolveAsRef(false));
+return resolvedSchema.schema.description(description);
+}
+
+
+
+
+
+

13.75. How can i define different description for a class attribute depending on usage?

+
+

For example let’s consider a Instance class with an email attribute:

+
+
+
+
public class PersonDTO {
+
+    @JsonProperty
+    private String email;
+
+    @JsonProperty
+    private String firstName;
+
+    @JsonProperty
+    private String lastName;
+
+
+}
+
+
+
+
+

If you want to define two different description for the email, you can set up 2 different schemas as follow:

+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+return new OpenAPI().components(new Components()
+.addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email" ))
+.addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email" )));
+}
+
+private Schema getFieldSchemaWithDifferentDescription(Class className, String description){
+    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+            .resolveAsResolvedSchema(
+                    new AnnotatedType(className).resolveAsRef(false));
+    return resolvedSchema.schema.addProperties("email", new StringSchema().description(description));
+}
+
+
+
+
+
+

13.76. Customizing swagger static resources

+
+

You can customize swagger documentation static resources located in META-INF/resources/webjars/swagger-ui/{swagger.version}/. The list of resources includes:

+
+
+
    +
  • +

    index.html

    +
  • +
  • +

    swagger-ui-bundle.js

    +
  • +
  • +

    swagger-ui.css

    +
  • +
  • +

    swagger-ui-standalone-preset.js

    +
  • +
  • +

    swagger-ui.css.map

    +
  • +
  • +

    swagger-ui-bundle.js.map

    +
  • +
  • +

    swagger-ui-standalone-preset.js.map

    +
  • +
  • +

    favicon-32x32.png

    +
  • +
+
+
+

To do this, you need to extend the implementation of SwaggerIndexPageTransformer

+
+
+
+
public class SwaggerCodeBlockTransformer
+       extends SwaggerIndexPageTransformer {
+  // < constructor >
+  @Override
+  public Resource transform(HttpServletRequest request,
+                            Resource resource,
+                            ResourceTransformerChain transformer)
+                            throws IOException {
+      if (resource.toString().contains("swagger-ui.css")) {
+          final InputStream is = resource.getInputStream();
+          final InputStreamReader isr = new InputStreamReader(is);
+          try (BufferedReader br = new BufferedReader(isr)) {
+              final String css = br.lines().collect(Collectors.joining());
+              final byte[] transformedContent = css.replace("old", "new").getBytes();
+              return  new TransformedResource(resource, transformedContent);
+          } // AutoCloseable br > isr > is
+      }
+      return super.transform(request, resource, transformer);
+  }
+
+}
+
+
+
+
+

Next, add transformer @Bean to your @Configuration

+
+
+
+
@Configuration
+public class OpenApiConfig {
+    @Bean
+    public SwaggerIndexTransformer swaggerIndexTransformer(
+            SwaggerUiConfigProperties a,
+            SwaggerUiOAuthProperties b,
+            SwaggerUiConfigParameters c,
+            SwaggerWelcomeCommon d) {
+        return new SwaggerCodeBlockTransformer(a, b, c, d);
+    }
+}
+
+
+
+
+

Illustrative example

+
+
+
+Illustrative example +
+
+
+
+

13.77. Is GraalVM supported ?

+
+

The native support available added in spring-boot 3. +If you have some time, do not hesitate to test it before the next release.

+
+
+

For the OpenAPI REST endpoints, you just need to build your application with the spring native profile.

+
+
+

If you give @OpenAPIDefinition or @SecurityScheme to a class that has no implementation, that class will disappear when you natively compile. +To avoid this, give the class a @Configuration.

+
+
+
+
@Configuration
+@OpenAPIDefinition(info = @Info(title = "My App", description = "description"))
+public class OpenAPIConfig {
+}
+
+
+
+
+

13.78. How to Integrate Open API 3 with Spring project (not Spring Boot)?

+
+

When your application is using spring without (spring-boot), you need to add beans and auto-configuration that are natively provided in spring-boot.

+
+
+

For example, lets assume you want load the swagger-ui in spring-mvc application:

+
+
+
    +
  • +

    You mainly, need to add the springdoc-openapi module

    +
  • +
+
+
+
+
<dependency>
+   <groupId>org.springdoc</groupId>
+   <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+   <version>last.version</version>
+</dependency>
+
+
+
+
    +
  • +

    If you don’t have the spring-boot and spring-boot-autoconfigure dependencies, you need to add them. And pay attention to the compatibility matrix, between you spring.version and spring-boot.version. For example, in this case (spring.version=5.1.12.RELEASE):

    +
  • +
+
+
+
+
        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+            <version>3.3.3</version>
+        </dependency>
+
+
+
+
    +
  • +

    Scan for the springdoc-openapi 'auto-configuration classes that spring-boot automatically loads for you.

    +
  • +
  • +

    Depending on your module, you can find them on the file: spring.factories of each springdoc-openapi module.

    +
  • +
+
+
+
+
@Configuration
+@EnableWebMvc
+public class WebConfig implements WebApplicationInitializer {
+
+    @Override
+    public void onStartup(ServletContext servletContext)  {
+        WebApplicationContext context = getContext();
+        servletContext.addListener(new ContextLoaderListener(context));
+        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet",
+                new DispatcherServlet(context));
+        dispatcher.setLoadOnStartup(1);
+        dispatcher.addMapping("/*");
+    }
+
+    private AnnotationConfigWebApplicationContext getContext() {
+        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+        context.register(this.getClass(),
+                SpringDocConfiguration.class,
+                SpringDocConfigProperties.class,
+                SpringDocSpecPropertiesConfiguration.class,
+                SpringDocWebMvcConfiguration.class,
+                MultipleOpenApiSupportConfiguration.class,
+                SwaggerConfig.class,
+                SwaggerUiConfigProperties.class,
+                SwaggerUiOAuthProperties.class,
+        );
+        return context;
+    }
+}
+
+
+
+
+
    +
  • +

    Depending on your module, you can find them on the file: org.springframework.boot.autoconfigure.AutoConfiguration.imports of each springdoc-openapi module.

    +
  • +
  • +

    For groups usage make sure your GroupedOpenApi Beans are scanned.

    +
  • +
  • +

    If additionally, you are using custom context path: /my-servlet-path. Make sure you declare the following property:

    +
  • +
+
+
+
+
spring.mvc.servlet.path=/my-servlet-path
+
+
+
+
+

13.79. What is the compatibility matrix of springdoc-openapi with spring-boot ?

+
+

springdoc-openapi 2.x is compatible with spring-boot 3.

+
+
+

In general, you should only pick the last stable version as per today 2.8.9.

+
+
+

More precisely, this the exhaustive list of spring-boot versions against which springdoc-openapi has been built:

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

Spring Boot Versions

Springdoc OpenAPI Versions

3.4.x

2.7.x - 2.8.x

3.3.x

2.6.x

3.2.x

2.3.x - 2.5.x

3.1.x

2.2.x

3.0.x

2.0.x - 2.1.x

2.7.x, 1.5.x

1.6.0+

2.6.x, 1.5.x

1.6.0+

2.5.x, 1.5.x

1.5.9+

2.4.x, 1.5.x

1.5.0+

2.3.x, 1.5.x

1.4.0+

2.2.x, 1.5.x

1.2.1+

2.0.x, 1.5.x

1.0.0+

+
+
+

13.80. Why am i getting an error: Swagger UI unable to render definition, when overriding the default spring registered HttpMessageConverter?

+
+

When overriding the default spring-boot registered HttpMessageConverter, you should have ByteArrayHttpMessageConverter registered as well to have proper springdoc-openapi support.

+
+
+
+
    converters.add(new ByteArrayHttpMessageConverter());
+    converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder.build()));
+
+
+
+
+ + + + + +
+ + +Order is very important, when registering HttpMessageConverters. +
+
+
+
+

13.81. Some parameters are not generated in the resulting OpenAPI spec.

+
+

The issue is caused by the changes introduced by Spring-Boot 3.2.0 +in particular for the Parameter Name Discovery. +This can be fixed by adding the -parameters arg to the Maven Compiler Plugin.

+
+
+
+
<plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <configuration>
+        <parameters>true</parameters>
+    </configuration>
+</plugin>
+
+
+
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/intro.html b/docs/intro.html new file mode 100644 index 0000000..9181077 --- /dev/null +++ b/docs/intro.html @@ -0,0 +1,91 @@ + + + + + + + +Introduction + + + + + + +
+
+
+ +
+
+

Introduction

+
+
+

springdoc-openapi java library helps to automate the generation of API documentation using spring boot projects. +springdoc-openapi works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations.

+
+
+

Automatically generates documentation in JSON/YAML and HTML format APIs. +This documentation can be completed by comments using swagger-api annotations.

+
+
+

This library supports:

+
+
+
    +
  • +

    OpenAPI 3

    +
  • +
  • +

    Spring-boot v3 (Java 17 & Jakarta EE 9)

    +
  • +
  • +

    JSR-303, specifically for @NotNull, @Min, @Max, and @Size.

    +
  • +
  • +

    Swagger-ui

    +
  • +
  • +

    OAuth 2

    +
  • +
  • +

    GraalVM native images

    +
  • +
+
+
+

The following video introduces the Library:

+
+
+
+spring.io conference +
+
+
+

This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal).

+
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/js/setup.js b/docs/js/setup.js new file mode 100755 index 0000000..ae5b1b7 --- /dev/null +++ b/docs/js/setup.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/docs/js/setup.js.map b/docs/js/setup.js.map new file mode 100755 index 0000000..2971105 --- /dev/null +++ b/docs/js/setup.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["setup/src/main/js/setup/layout.js","setup/node_modules/browser-pack-flat/_prelude","setup/node_modules/lodash/_baseDelay.js","setup/switchtheme.js","setup/node_modules/lodash/identity.js","setup/node_modules/lodash/_apply.js","setup/node_modules/lodash/_overRest.js","setup/node_modules/lodash/constant.js","setup/node_modules/lodash/_freeGlobal.js","setup/node_modules/lodash/_root.js","setup/node_modules/lodash/_Symbol.js","setup/node_modules/lodash/_getRawTag.js","setup/node_modules/lodash/_objectToString.js","setup/node_modules/lodash/_baseGetTag.js","setup/node_modules/lodash/isObject.js","setup/node_modules/lodash/isFunction.js","setup/node_modules/lodash/_isMasked.js","setup/node_modules/lodash/_coreJsData.js","setup/node_modules/lodash/_toSource.js","setup/node_modules/lodash/_baseIsNative.js","setup/node_modules/lodash/_getValue.js","setup/node_modules/lodash/_getNative.js","setup/node_modules/lodash/_defineProperty.js","setup/node_modules/lodash/_baseSetToString.js","setup/node_modules/lodash/_shortOut.js","setup/node_modules/lodash/_setToString.js","setup/node_modules/lodash/_baseRest.js","setup/node_modules/lodash/_trimmedEndIndex.js","setup/node_modules/lodash/_baseTrim.js","setup/node_modules/lodash/isObjectLike.js","setup/node_modules/lodash/isSymbol.js","setup/node_modules/lodash/toNumber.js","setup/node_modules/lodash/delay.js","setup/src/main/js/setup/switchtheme.js","setup/node_modules/browser-pack-flat/_postlude"],"names":["document","getElementsByTagName","classList","add","_$baseDelay_3","func","wait","args","TypeError","setTimeout","apply","undefined","_$identity_25","value","_$apply_2","thisArg","length","call","nativeMax","Math","max","_$overRest_17","start","transform","arguments","index","array","Array","otherArgs","this","_$constant_23","_$freeGlobal_11","global","freeGlobal","Object","self","window","freeSelf","_$root_18","Function","_$Symbol_1","Symbol","objectProto","prototype","hasOwnProperty","nativeObjectToString","toString","symToStringTag","toStringTag","_$getRawTag_13","isOwn","tag","unmasked","e","result","__nativeObjectToString_16","_$objectToString_16","__symToStringTag_4","_$baseGetTag_4","_$isObject_27","type","uid","_$isFunction_26","_$coreJsData_9","maskSrcKey","exec","keys","IE_PROTO","_$isMasked_15","funcToString","_$toSource_21","reIsHostCtor","__funcProto_5","__objectProto_5","__funcToString_5","__hasOwnProperty_5","reIsNative","RegExp","replace","_$baseIsNative_5","test","_$getValue_14","object","key","_$getNative_12","_$defineProperty_10","_$baseSetToString_7","string","configurable","enumerable","writable","nativeNow","Date","now","_$shortOut_20","count","lastCalled","stamp","remaining","_$setToString_19","reWhitespace","_$trimmedEndIndex_22","charAt","reTrimStart","_$baseTrim_8","slice","_$isObjectLike_28","_$isSymbol_29","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","parseInt","_$toNumber_30","other","valueOf","isBinary","_$delay_24","_$baseRest_6","localStorage","htmlElement","documentElement","prefersDarkColorScheme","matchMedia","isInitialThemeDark","theme","getItem","matches","onThemeChange","checked","saveTheme","remove","setItem","addEventListener","toggleCheckboxElement","querySelector","bind"],"mappings":"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","file":"setup.js","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(function () {\n \"use strict\";\n document.getElementsByTagName(\"html\")[0].classList.add(\"js\");\n})();\n","(function(){\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\nfunction baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n}\n\nmodule.exports = baseDelay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n const localStorage = window.localStorage;\n const htmlElement = document.documentElement;\n const prefersDarkColorScheme = window.matchMedia(\n \"(prefers-color-scheme: dark)\"\n );\n\n swithInitialTheme();\n window.addEventListener(\"load\", onWindowLoad);\n\n function swithInitialTheme() {\n if (isInitialThemeDark()) {\n htmlElement.classList.add(\"dark-theme\");\n }\n }\n\n function onWindowLoad() {\n const toggleCheckboxElement = document.querySelector(\n \"#switch-theme-checkbox\"\n );\n toggleCheckboxElement.checked = isInitialThemeDark();\n toggleCheckboxElement.addEventListener(\n \"change\",\n onThemeChange.bind(toggleCheckboxElement)\n );\n }\n\n function isInitialThemeDark() {\n const theme = loadTheme();\n return theme ? theme === \"dark\" : prefersDarkColorScheme.matches;\n }\n\n function onThemeChange() {\n if (this.checked) {\n delay(function () {\n htmlElement.classList.add(\"dark-theme\");\n }, 100);\n saveTheme(\"dark\");\n } else {\n delay(function () {\n htmlElement.classList.remove(\"dark-theme\");\n }, 100);\n saveTheme(\"light\");\n }\n }\n\n function saveTheme(theme) {\n if (localStorage) {\n localStorage.setItem(\"theme\", theme);\n }\n }\n\n function loadTheme() {\n return localStorage !== null ? localStorage.getItem(\"theme\") : null;\n }\n})();\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n","var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","var baseDelay = require('./_baseDelay'),\n baseRest = require('./_baseRest'),\n toNumber = require('./toNumber');\n\n/**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\nvar delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n});\n\nmodule.exports = delay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n const localStorage = window.localStorage;\n const htmlElement = document.documentElement;\n const prefersDarkColorScheme = window.matchMedia(\n \"(prefers-color-scheme: dark)\"\n );\n\n swithInitialTheme();\n window.addEventListener(\"load\", onWindowLoad);\n\n function swithInitialTheme() {\n if (isInitialThemeDark()) {\n htmlElement.classList.add(\"dark-theme\");\n }\n }\n\n function onWindowLoad() {\n const toggleCheckboxElement = document.querySelector(\n \"#switch-theme-checkbox\"\n );\n toggleCheckboxElement.checked = isInitialThemeDark();\n toggleCheckboxElement.addEventListener(\n \"change\",\n onThemeChange.bind(toggleCheckboxElement)\n );\n }\n\n function isInitialThemeDark() {\n const theme = loadTheme();\n return theme ? theme === \"dark\" : prefersDarkColorScheme.matches;\n }\n\n function onThemeChange() {\n if (this.checked) {\n delay(function () {\n htmlElement.classList.add(\"dark-theme\");\n }, 100);\n saveTheme(\"dark\");\n } else {\n delay(function () {\n htmlElement.classList.remove(\"dark-theme\");\n }, 100);\n saveTheme(\"light\");\n }\n }\n\n function saveTheme(theme) {\n if (localStorage) {\n localStorage.setItem(\"theme\", theme);\n }\n }\n\n function loadTheme() {\n return localStorage !== null ? localStorage.getItem(\"theme\") : null;\n }\n})();\n","\n}());"]} \ No newline at end of file diff --git a/docs/js/site.js b/docs/js/site.js new file mode 100755 index 0000000..24a40b4 --- /dev/null +++ b/docs/js/site.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?"Expand 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 s(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 r=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(!r(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){r(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+)?)",p="\\b(0b[01]+)",f={begin:"\\\\[\\s\\S]",relevance:0},_={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[f]},E={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[f]},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=s({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("#","$"),M={className:"number",begin:m,relevance:0},O={className:"number",begin:h,relevance:0},k={className:"number",begin:p,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},S={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[f,{begin:/\[/,end:/\]/,relevance:0,contains:[f]}]}]},A={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:p,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.*/)),s({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:f,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:M,C_NUMBER_MODE:O,BINARY_NUMBER_MODE:k,CSS_NUMBER_MODE:R,REGEXP_MODE:S,TITLE_MODE:A,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=s(e.classNameAliases||{}),function n(a,r){const o=a;if(a.isCompiled)return o;[I].forEach((e=>e(a,r))),e.compilerExtensions.forEach((e=>e(a,r))),a.__beforeBegin=null,[B,$,j].forEach((e=>e(a,r))),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),r&&(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&&r.terminatorEnd&&(o.terminatorEnd+=(a.end?"|":"")+r.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 s(e,{variants:null},n)})));if(e.cachedVariants)return e.cachedVariants;if(H(e))return s(e,{starts:e.starts?s(e.starts):null});if(Object.isFrozen(e))return s(e);return e}("self"===e?a:e)}))),a.contains.forEach((function(e){n(e,o)})),a.starts&&n(a.starts,r),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=F(e);if(!a.length)return;const s=document.createElement("div");s.innerHTML=n.value,n.value=function(e,n,t){let a=0,s="";const r=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function c(e){s+=""}function g(e){("start"===e.event?l:c)(e.node)}for(;e.length||n.length;){let n=o();if(s+=i(t.substring(a,n[0].offset)),a=n[0].offset,n===e){r.reverse().forEach(c);do{g(n.splice(0,1)[0]),n=o()}while(n===e&&n.length&&n[0].offset===a);r.reverse().forEach(l)}else"start"===n[0].event?r.push(n[0].node):r.pop(),g(n.splice(0,1)[0])}return s+i(t.substr(a))}(a,F(s),t)}};function q(e){return e.nodeName.toLowerCase()}function F(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),q(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=s,ee=Symbol("nomatch");var ne=function(e){const t=Object.create(null),i=Object.create(null),s=[];let r=!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="",s="";"object"==typeof n?(i=e,t=n.ignoreIllegals,s=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"),s=e,i=n);const r={code:i,language:s};O("before:highlight",r);const o=r.result?r.result:m(r.language,r.code,t,a);return o.code=r.code,O("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!=M.subLanguage?function(){if(""===R)return;let e=null;if("string"==typeof M.subLanguage){if(!t[M.subLanguage])return void k.addText(R);e=m(M.subLanguage,R,!0,O[M.subLanguage]),O[M.subLanguage]=e.top}else e=h(R,M.subLanguage.length?M.subLanguage:null);M.relevance>0&&(S+=e.relevance),k.addSublanguage(e.emitter,e.language)}():function(){if(!M.keywords)return void k.addText(R);let e=0;M.keywordPatternRe.lastIndex=0;let n=M.keywordPatternRe.exec(R),t="";for(;n;){t+=R.substring(e,n.index);const a=c(M,n);if(a){const[e,i]=a;if(k.addText(t),t="",S+=i,e.startsWith("_"))t+=n[0];else{const t=N.classNameAliases[e]||e;k.addKeyword(n[0],t)}}else t+=n[0];e=M.keywordPatternRe.lastIndex,n=M.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),M=Object.create(e,{parent:{value:M}}),M}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 p(e){return 0===M.matcher.regexIndex?(R+=e[0],1):(C=!0,0)}function f(e){const n=e[0],t=e.rule,i=new a(t),s=[t.__beforeBegin,t["on:begin"]];for(const t of s)if(t&&(t(e,i),i.isMatchIgnored))return p(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(M,e,a);if(!i)return ee;const s=M;s.skip?R+=t:(s.returnEnd||s.excludeEnd||(R+=t),g(),s.excludeEnd&&(R=t));do{M.className&&k.closeNode(),M.skip||M.subLanguage||(S+=M.relevance),M=M.parent}while(M!==i.parent);return i.starts&&(i.endSameAsBegin&&(i.starts.endRe=i.endRe),u(i.starts)),s.returnEnd?0:t.length}let E={};function v(t,a){const s=a&&a[0];if(R+=t,null==s)return g(),0;if("begin"===E.type&&"end"===a.type&&E.index===a.index&&""===s){if(R+=n.slice(a.index,a.index+1),!r){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 f(a);if("illegal"===a.type&&!i){const e=new Error('Illegal lexeme "'+s+'" for mode "'+(M.className||"")+'"');throw e.mode=M,e}if("end"===a.type){const e=_(a);if(e!==ee)return e}if("illegal"===a.type&&""===s)return 1;if(T>1e5&&T>3*a.index){throw new Error("potential infinite loop, way more iterations than matches")}return R+=s,s.length}const N=w(e);if(!N)throw Q(l.replace("{}",e)),new Error('Unknown language: "'+e+'"');const y=K(N,{plugins:s});let x="",M=o||y;const O={},k=new d.__emitter(d);!function(){const e=[];for(let n=M;n!==N;n=n.parent)n.className&&e.unshift(n.className);e.forEach((e=>k.openNode(e)))}();let R="",S=0,A=0,T=0,C=!1;try{for(M.matcher.considerAll();;){T++,C?C=!1:M.matcher.considerAll(),M.matcher.lastIndex=A;const e=M.matcher.exec(n);if(!e)break;const t=v(n.substring(A,e.index),e);A=e.index+t}return v(n.substr(A)),k.closeAllNodes(),k.finalize(),x=k.toHTML(),{relevance:Math.floor(S),value:x,language:e,illegal:!1,emitter:k,top:M}}catch(t){if(t.message&&t.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:t.message,context:n.slice(A-100,A+100),mode:t.mode},sofar:x,relevance:0,value:J(n),emitter:k};if(r)return{illegal:!1,relevance:0,value:J(n),emitter:k,language:e,top:M,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(M).map((n=>m(n,e,!1)));i.unshift(a);const s=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})),[r,o]=s,l=r;return l.second_best=o,l}const p={"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,"
"))}},f=/^(<[^>]+>|\t)+/gm,_={"after:highlightElement":({result:e})=>{d.tabReplace&&(e.value=e.value.replace(f,(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;O("before:highlightElement",{el:e,language:t}),n=e;const a=n.textContent,s=t?b(a,{language:t,ignoreIllegals:!0}):h(a);O("after:highlightElement",{el:e,result:s,text:a}),e.innerHTML=s.value,function(e,n,t){const a=n?i[n]:t;e.classList.add("hljs"),a&&e.classList.add(a)}(e,t,s.language),e.result={language:s.language,re:s.relevance,relavance:s.relevance},s.second_best&&(e.second_best={language:s.second_best.language,re:s.second_best.relevance,relavance:s.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 M(e){const n=w(e);return n&&!n.disableAutodetect}function O(e,n){const t=e;s.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)),!r)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:M,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),s.push(e)},vuePlugin:Z(e).VuePlugin}),e.debugMode=function(){r=!1},e.safeMode=function(){r=!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(p),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 se=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"})]}},s={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n,a]};a.contains.push(s);const r={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,r,e.HASH_COMMENT_MODE,i,s,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},n]}};const re=["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("+re.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 _e(e,n={}){return n.variants=e,n}var Ee=function(e){const n="[A-Za-z0-9_$]+",t=_e([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=_e([e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]),s=_e([{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,s,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,s,a,i,"self"]},{className:"symbol",begin:"^[ \t]*"+fe(n+":"),excludeBegin:!0,end:n+":",relevance:0}],illegal:/#|<\//}};function ve(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ne=function(e){const n="HTTP/(2|1\\.[01])",t={className:"attribute",begin:ve("^",/[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})]}},ye="\\.([0-9](_*[0-9])*)",we="[0-9a-fA-F](_*[0-9a-fA-F])*",xe={className:"number",variants:[{begin:`(\\b([0-9](_*[0-9])*)((${ye})|\\.)?|(${ye}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:`\\b([0-9](_*[0-9])*)((${ye})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${ye})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{begin:`\\b0[xX]((${we})\\.?|(${we})?\\.(${we}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${we})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};var Me=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=xe;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$_]*",ke=["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"],Re=["true","false","null","undefined","NaN","Infinity"],Se=[].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 Te("(?=",e,")")}function Te(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ce=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:s,contains:p}]}]},{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:s,contains:["self",e.inherit(e.TITLE_MODE,{begin:n}),f],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[f,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",f]},{begin:"(get|set)\\s+(?="+n+"\\()",end:/\{/,keywords:"get set",contains:[e.inherit(e.TITLE_MODE,{begin:n}),{begin:/\(\)/},f]},{begin:/\$[(.]/}]}};var De=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},s={begin:/\{/,end:/\}/,contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(i,{begin:/:/})].concat(t),illegal:"\\S"},r={begin:"\\[",end:"\\]",contains:[e.inherit(i)],illegal:"\\S"};return a.push(s,r),t.forEach((function(e){a.push(e)})),{name:"JSON",contains:a,keywords:n,illegal:"\\S"}},Le="\\.([0-9](_*[0-9])*)",Be="[0-9a-fA-F](_*[0-9a-fA-F])*",$e={className:"number",variants:[{begin:`(\\b([0-9](_*[0-9])*)((${Le})|\\.)?|(${Le}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:`\\b([0-9](_*[0-9])*)((${Le})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${Le})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{begin:`\\b0[xX]((${Be})\\.?|(${Be})?\\.(${Be}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${Be})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};var Ie=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},s={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(s);const r={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(s,{className:"meta-string"})]}]},l=$e,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,r,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,r,o,s,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},r,o]},s,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},l]}};function je(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var ze=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:je(/\[.+?\]\(/,/[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 s=[n,t];return a.contains=a.contains.concat(s),i.contains=i.contains.concat(s),s=s.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:s},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:s}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:s,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 Pe=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 Ue=function(e){const n={$pattern:/-?[A-z\.\-]+\b/,keyword:"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter",built_in:"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write"},t={begin:"`[\\s\\S]",relevance:0},a={className:"variable",variants:[{begin:/\$\B/},{className:"keyword",begin:/\$this/},{begin:/\$[\w\d][\w\d_:]*/}]},i={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[t,a,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},s={className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},r=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]}),o={className:"built_in",variants:[{begin:"(".concat("Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where",")+(-)[\\w\\d]+")}]},l={className:"class",beginKeywords:"class enum",end:/\s*[{]/,excludeEnd:!0,relevance:0,contains:[e.TITLE_MODE]},c={className:"function",begin:/function\s+/,end:/\s*\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:"function",relevance:0,className:"keyword"},{className:"title",begin:/\w[\w\d]*((-)[\w\d]+)*/,relevance:0},{begin:/\(/,end:/\)/,className:"params",relevance:0,contains:[a]}]},g={begin:/using\s/,end:/$/,returnBegin:!0,contains:[i,s,{className:"keyword",begin:/(using|assembly|command|module|namespace|type)/}]},d={variants:[{className:"operator",begin:"(".concat("-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor",")\\b")},{className:"literal",begin:/(-)[\w\d]+/,relevance:0}]},u={className:"function",begin:/\[.*\]\s*[\w]+[ ]??\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:"keyword",begin:"(".concat(n.keyword.toString().replace(/\s/g,"|"),")\\b"),endsParent:!0,relevance:0},e.inherit(e.TITLE_MODE,{endsParent:!0})]},b=[u,r,t,e.NUMBER_MODE,i,s,o,a,{className:"literal",begin:/\$(null|true|false)\b/},{className:"selector-tag",begin:/@\B/,relevance:0}],m={begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat("self",b,{begin:"("+["string","char","byte","int","long","bool","decimal","single","double","DateTime","xml","array","hashtable","void"].join("|")+")",className:"built_in",relevance:0},{className:"type",begin:/[\.\w\d]+/,relevance:0})};return u.contains.unshift(m),{name:"PowerShell",aliases:["ps","ps1"],case_insensitive:!0,keywords:n,contains:b.concat(l,c,g,d,m)}};var Ke=function(e){var n="[ \\t\\f]*",t=n+"[:=]"+n,a="[ \\t\\f]+",i="("+t+"|"+"[ \\t\\f]+)",s="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",r="([^\\\\:= \\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:s+t,relevance:1},{begin:s+a,relevance:0}],contains:[{className:"attr",begin:s,endsParent:!0,relevance:0}],starts:o},{begin:r+i,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:r,endsParent:!0,relevance:0}],starts:o},{className:"attr",relevance:0,begin:r+n+"$"}]}};function He(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ze=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:">"},s=[e.COMMENT("#","$",{contains:[a]}),e.COMMENT("^=begin","^=end",{contains:[a],relevance:10}),e.COMMENT("^__END__","\\n$")],r={className:"subst",begin:/#\{/,end:/\}/,keywords:t},o={className:"string",contains:[e.BACKSLASH_ESCAPE,r],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,r]})]}]},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(s)},{className:"function",begin:He(/def\s+/,(u=n+"\\s*(\\(|;|$)",He("(?=",u,")"))),relevance:0,keywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),g].concat(s)},{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,r],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,s),relevance:0}].concat(i,s);var u;r.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 s.unshift(i),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:t,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(b).concat(s).concat(d)}};var Ge=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},s={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]},r={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,r,s,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}};var qe=function(e){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#]/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}};function Fe(e){return e?"string"==typeof e?e:e.source:null}function We(...e){return e.map((e=>Fe(e))).join("")}function Qe(...e){return"("+e.map((e=>Fe(e))).join("|")+")"}var Xe=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"],s=["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"],r=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:We(/\b/,Qe(...r),/\s*\(/),keywords:{built_in:r}};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(...s),keywords:{$pattern:/[\w\.]+/,keyword:o.concat(s),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 Ve(e){return e?"string"==typeof e?e:e.source:null}function Je(e){return Ye("(?=",e,")")}function Ye(...e){return e.map((e=>Ve(e))).join("")}function en(...e){return"("+e.map((e=>Ve(e))).join("|")+")"}var nn=function(e){const n=Ye(/[A-Z_]/,Ye("(",/[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:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),r=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,r,s,i,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[a,i,r,s]}]}]},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:Ye(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:o}]},{className:"tag",begin:Ye(/<\//,Je(Ye(n,/>/))),contains:[{className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}};var tn=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,{}[\]]+/}]}),s={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"},r={end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},o={begin:/\{/,end:/\}/,contains:[r],illegal:"\\n",relevance:0},l={begin:"\\[",end:"\\]",contains:[r],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}},s,{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},o,l,a],g=[...c];return g.pop(),g.push(i),r.contains=g,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:c}};!function(){"use strict";ne.registerLanguage("asciidoc",ae),ne.registerLanguage("bash",se),ne.registerLanguage("css",ue),ne.registerLanguage("diff",be),ne.registerLanguage("dockerfile",me),ne.registerLanguage("dos",he),ne.registerLanguage("gradle",pe),ne.registerLanguage("groovy",Ee),ne.registerLanguage("http",Ne),ne.registerLanguage("java",Me),ne.registerLanguage("javascript",Ce),ne.registerLanguage("json",De),ne.registerLanguage("kotlin",Ie),ne.registerLanguage("markdown",ze),ne.registerLanguage("nix",Pe),ne.registerLanguage("powershell",Ue),ne.registerLanguage("properties",Ke),ne.registerLanguage("ruby",Ze),ne.registerLanguage("scala",Ge),ne.registerLanguage("shell",qe),ne.registerLanguage("sql",Xe),ne.registerLanguage("xml",nn),ne.registerLanguage("yaml",tn),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,n){let o=t.nextElementSibling;for(;o;){if(o.matches(e))return o;if(o.matches(n))return;o=o.nextElementSibling}}(t,".colist",".listingblock");s&&c.append(s);const i=n('
'+o+"
");return i.dataset.blockName=o,c.dataset.blockName=o,e.append(i),{tabElement:i,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"))i(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 i(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=i(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/docs/js/site.js.map b/docs/js/site.js.map new file mode 100755 index 0000000..89de670 --- /dev/null +++ b/docs/js/site.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["site/src/main/js/site/anchorrewrite.js","site/anchorrewrite.js","site/src/main/js/site/author.js","site/author.js","site/node_modules/browser-pack-flat/_prelude","site/node_modules/lodash/_baseDelay.js","site/codetools.js","site/node_modules/lodash/identity.js","site/node_modules/lodash/_apply.js","site/node_modules/lodash/_overRest.js","site/node_modules/lodash/constant.js","site/node_modules/lodash/_freeGlobal.js","site/node_modules/lodash/_root.js","site/node_modules/lodash/_Symbol.js","site/node_modules/lodash/_getRawTag.js","site/node_modules/lodash/_objectToString.js","site/node_modules/lodash/_baseGetTag.js","site/node_modules/lodash/isObject.js","site/node_modules/lodash/isFunction.js","site/node_modules/lodash/_isMasked.js","site/node_modules/lodash/_coreJsData.js","site/node_modules/lodash/_toSource.js","site/node_modules/lodash/_baseIsNative.js","site/node_modules/lodash/_getValue.js","site/node_modules/lodash/_getNative.js","site/node_modules/lodash/_defineProperty.js","site/node_modules/lodash/_baseSetToString.js","site/node_modules/lodash/_shortOut.js","site/node_modules/lodash/_setToString.js","site/node_modules/lodash/_baseRest.js","site/node_modules/lodash/_trimmedEndIndex.js","site/node_modules/lodash/_baseTrim.js","site/node_modules/lodash/isObjectLike.js","site/node_modules/lodash/isSymbol.js","site/node_modules/lodash/toNumber.js","site/node_modules/lodash/delay.js","site/src/main/js/site/codetools.js","site/node_modules/browser-pack-flat/_postlude","site/node_modules/highlight.js/lib/core.js","site/highlight.js","site/node_modules/highlight.js/lib/languages/asciidoc.js","site/node_modules/highlight.js/lib/languages/bash.js","site/node_modules/highlight.js/lib/languages/css.js","site/node_modules/highlight.js/lib/languages/diff.js","site/node_modules/highlight.js/lib/languages/dockerfile.js","site/node_modules/highlight.js/lib/languages/dos.js","site/node_modules/highlight.js/lib/languages/gradle.js","site/node_modules/highlight.js/lib/languages/groovy.js","site/node_modules/highlight.js/lib/languages/http.js","site/node_modules/highlight.js/lib/languages/java.js","site/node_modules/highlight.js/lib/languages/javascript.js","site/node_modules/highlight.js/lib/languages/json.js","site/node_modules/highlight.js/lib/languages/kotlin.js","site/node_modules/highlight.js/lib/languages/markdown.js","site/node_modules/highlight.js/lib/languages/nix.js","site/node_modules/highlight.js/lib/languages/powershell.js","site/node_modules/highlight.js/lib/languages/properties.js","site/node_modules/highlight.js/lib/languages/ruby.js","site/node_modules/highlight.js/lib/languages/scala.js","site/node_modules/highlight.js/lib/languages/shell.js","site/node_modules/highlight.js/lib/languages/sql.js","site/node_modules/highlight.js/lib/languages/xml.js","site/node_modules/highlight.js/lib/languages/yaml.js","site/src/main/js/site/highlight.js","site/src/main/js/site/tabs.js","site/tabs.js","site/toc.js","site/node_modules/lodash/now.js","site/node_modules/lodash/debounce.js","site/node_modules/lodash/throttle.js","site/src/main/js/site/toc.js"],"names":["onChange","element","document","getElementById","anchor","window","location","hash","substr","rewrites","seen","console","debug","includes","error","push","updateAnchor","JSON","parse","innerHTML","addEventListener","candidate","lastAuthorElement","classList","contains","nextElementSibling","add","markLastAuthor","_$baseDelay_3","func","wait","args","TypeError","setTimeout","apply","undefined","_$identity_25","value","_$apply_2","thisArg","length","call","nativeMax","Math","max","_$overRest_17","start","transform","arguments","index","array","Array","otherArgs","this","_$constant_23","_$freeGlobal_11","global","freeGlobal","Object","self","freeSelf","_$root_18","Function","_$Symbol_1","Symbol","objectProto","prototype","hasOwnProperty","nativeObjectToString","toString","symToStringTag","toStringTag","_$getRawTag_13","isOwn","tag","unmasked","e","result","__nativeObjectToString_16","_$objectToString_16","__symToStringTag_4","_$baseGetTag_4","_$isObject_27","type","uid","_$isFunction_26","_$coreJsData_9","maskSrcKey","exec","keys","IE_PROTO","_$isMasked_15","funcToString","_$toSource_21","reIsHostCtor","__funcProto_5","__objectProto_5","__funcToString_5","__hasOwnProperty_5","reIsNative","RegExp","replace","_$baseIsNative_5","test","_$getValue_14","object","key","_$getNative_12","_$defineProperty_10","_$baseSetToString_7","string","configurable","enumerable","writable","nativeNow","Date","now","_$shortOut_20","count","lastCalled","stamp","remaining","_$setToString_19","reWhitespace","_$trimmedEndIndex_22","charAt","reTrimStart","_$baseTrim_8","slice","_$isObjectLike_28","_$isSymbol_29","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","parseInt","_$toNumber_30","other","valueOf","isBinary","_$delay_24","_$baseRest_6","onCopyButtonClick","preElement","copy","querySelector","cloneNode","hideWhenFoldedElement","querySelectorAll","parentNode","removeChild","text","innerText","navigator","clipboard","writeText","then","markClicked","bind","clearClicked","remove","onFoldUnfoldButtonClick","codeElement","unfolding","toggle","updateFoldUnfoldButton","button","unfold","label","title","codeToolsElement","createElement","className","addButtons","appendChild","numberOfButtons","hasHideWhenFoldedSpans","foldUnfoldButton","createButton","addFoldUnfoldButton","copyButton","copiedPopup","addCopyButton","buttonElement","labelElement","createTextNode","addCodeToolElements","deepFreeze","obj","Map","clear","delete","set","Error","Set","freeze","getOwnPropertyNames","forEach","name","prop","isFrozen","deepFreezeEs6","_default","default","Response","constructor","mode","data","isMatchIgnored","ignoreMatch","escapeHTML","inherit","original","objects","create","emitsWrappingTags","node","kind","HTMLRenderer","parseTree","options","buffer","classPrefix","walk","addText","openNode","sublanguage","span","closeNode","TokenTree","rootNode","children","stack","top","root","pop","closeAllNodes","toJSON","stringify","builder","_walk","static","child","every","el","join","_collapse","TokenTreeEmitter","super","addKeyword","addSublanguage","emitter","toHTML","finalize","source","re","BACKREF_RE","IDENT_RE","UNDERSCORE_IDENT_RE","NUMBER_RE","C_NUMBER_RE","BINARY_NUMBER_RE","BACKSLASH_ESCAPE","begin","relevance","APOS_STRING_MODE","end","illegal","QUOTE_STRING_MODE","PHRASAL_WORDS_MODE","COMMENT","modeOptions","C_LINE_COMMENT_MODE","C_BLOCK_COMMENT_MODE","HASH_COMMENT_MODE","NUMBER_MODE","C_NUMBER_MODE","BINARY_NUMBER_MODE","CSS_NUMBER_MODE","REGEXP_MODE","TITLE_MODE","UNDERSCORE_TITLE_MODE","METHOD_GUARD","MODES","__proto__","MATCH_NOTHING_RE","RE_STARTERS_RE","SHEBANG","opts","beginShebang","binary","map","x","concat","m","resp","END_SAME_AS_BEGIN","assign","_beginMatch","skipIfhasPrecedingDot","match","response","input","beginKeywords","parent","split","__beforeBegin","keywords","compileIllegal","_parent","isArray","either","compileMatch","compileRelevance","COMMON_KEYWORDS","compileKeywords","rawKeywords","caseInsensitive","compiledKeywords","compileList","keywordList","toLowerCase","keyword","pair","scoreForKeyword","providedScore","Number","commonKeyword","compileLanguage","language","plugins","langRe","case_insensitive","MultiRegex","matchIndexes","regexes","matchAt","position","addRule","countMatchGroups","compile","terminators","matcherRe","regexps","separator","numCaptures","regex","offset","out","substring","String","lastIndex","s","i","findIndex","matchData","splice","ResumableMultiRegex","rules","multiRegexes","regexIndex","getMatcher","matcher","resumingScanAtSamePosition","considerAll","m2","compilerExtensions","classNameAliases","compileMode","cmode","isCompiled","ext","keywordPattern","$pattern","lexemes","keywordPatternRe","beginRe","endSameAsBegin","endsWithParent","endRe","terminatorEnd","illegalRe","c","variants","cachedVariants","variant","dependencyOnParent","starts","expandOrCloneMode","mm","term","rule","buildModeRegex","BuildVuePlugin","hljs","Component","props","detectedLanguage","unknownLanguage","computed","highlighted","autoDetect","getLanguage","warn","code","highlightAuto","highlight","ignoreIllegals","autodetect","Boolean","render","class","domProps","VuePlugin","install","Vue","component","mergeHTMLPlugin","originalStream","nodeStream","resultNode","processed","nodeStack","selectStream","event","open","attributeString","attr","nodeName","attributes","close","stream","reverse","mergeStreams","_nodeStream","firstChild","nextSibling","nodeType","nodeValue","seenDeprecations","message","log","deprecated","version","escape$1","inherit$1","NO_MATCH","_$highlight_1","languages","aliases","SAFE_MODE","fixMarkupRe","LANGUAGE_NOT_FOUND","PLAINTEXT_LANGUAGE","disableAutodetect","noHighlightRe","languageDetectRe","tabReplace","useBR","__emitter","shouldNotHighlight","languageName","codeOrlanguageName","optionsOrCode","continuation","context","fire","_highlight","codeToHighlight","keywordData","matchText","processBuffer","subLanguage","modeBuffer","continuations","processSubLanguage","buf","keywordRelevance","startsWith","cssClass","processKeywords","startNewMode","endOfMode","matchPlusRemainder","matched","lexeme","endsParent","doIgnore","resumeScanAtSamePosition","doBeginMatch","newMode","beforeCallbacks","cb","skip","excludeBegin","returnBegin","doEndMatch","endMode","origin","returnEnd","excludeEnd","lastMatch","processLexeme","textBeforeMatch","err","badRule","iterations","md","list","current","unshift","item","processContinuations","processedCount","floor","illegalBy","msg","sofar","errorRaised","languageSubset","plaintext","justTextHighlightResult","results","filter","autoDetection","sorted","sort","a","b","supersetOf","best","secondBest","second_best","brPlugin","TAB_REPLACE_RE","tabReplacePlugin","highlightElement","block","classes","find","_class","blockLanguage","textContent","currentLang","resultLang","updateClassName","relavance","initHighlighting","called","wantsHighlight","highlightAll","readyState","registerAliases","aliasList","alias","lang","plugin","fixMarkup","arg","html","highlightBlock","configure","userOptions","initHighlightingOnLoad","registerLanguage","languageDefinition","error$1","rawDefinition","unregisterLanguage","listLanguages","requireLanguage","addPlugin","upgradePluginAPI","vuePlugin","debugMode","safeMode","versionString","HLJS","__concat_2","__source_2","_$asciidoc_2","STRONG","EMPHASIS","__concat_3","__source_3","_$bash_3","VAR","BRACED_VAR","SUBST","HERE_DOC","QUOTE_STRING","ARITHMETIC","KNOWN_SHEBANG","FUNCTION","literal","built_in","TAGS","MEDIA_FEATURES","PSEUDO_CLASSES","PSEUDO_ELEMENTS","ATTRIBUTES","lookahead","__source_4","__concat_4","_$css_4","modes","IMPORTANT","HEXCOLOR","ATTRIBUTE_SELECTOR_MODE","__MODES_4","STRINGS","keyframePosition","attribute","_$diff_5","_$dockerfile_6","_$dos_7","_$gradle_8","__lookahead_9","__source_9","__concat_9","_$groovy_9","REGEXP","NUMBER","STRING","__concat_10","__source_10","_$http_10","VERSION","HEADER","HEADERS_AND_BODY","frac","hexDigits","NUMERIC","_$java_11","JAVA_IDENT_RE","KEYWORDS","ANNOTATION","__IDENT_RE_12","LITERALS","BUILT_INS","__lookahead_12","__concat_12","__source_12","_$javascript_12","IDENT_RE$1","FRAGMENT","XML_TAG","isTrulyOpeningTag","afterMatchIndex","nextChar","after","indexOf","hasClosingTag","KEYWORDS$1","decimalInteger","HTML_TEMPLATE","CSS_TEMPLATE","TEMPLATE_STRING","SUBST_INTERNALS","SUBST_AND_COMMENTS","PARAMS_CONTAINS","PARAMS","exports","_$json_13","ALLOWED_COMMENTS","TYPES","VALUE_CONTAINER","OBJECT","ARRAY","__frac_14","__hexDigits_14","__NUMERIC_14","_$kotlin_14","LABEL","VARIABLE","ANNOTATION_USE_SITE","KOTLIN_NUMBER_MODE","KOTLIN_NESTED_COMMENT","KOTLIN_PAREN_TYPE","KOTLIN_PAREN_TYPE2","__concat_15","__source_15","_$markdown_15","INLINE_HTML","LINK","BOLD","ITALIC","CONTAINABLE","_$nix_16","NIX_KEYWORDS","ANTIQUOTE","EXPRESSIONS","_$powershell_17","BACKTICK_ESCAPE","APOS_STRING","PS_COMMENT","CMDLETS","PS_CLASS","PS_FUNCTION","PS_USING","PS_ARGUMENTS","PS_METHODS","GENTLEMANS_SET","PS_TYPE","_$properties_18","WS0","EQUAL_DELIM","WS_DELIM","DELIM","KEY_ALPHANUM","KEY_OTHER","DELIM_AND_VALUE","__concat_19","__source_19","_$ruby_19","RUBY_METHOD_RE","RUBY_KEYWORDS","YARDOCTAG","IRB_OBJECT","COMMENT_MODES","digits","RUBY_DEFAULT_CONTAINS","IRB_DEFAULT","_$scala_20","TYPE","NAME","CLASS","METHOD","_$shell_21","__source_22","__concat_22","__either_22","_$sql_22","COMMENT_MODE","RESERVED_FUNCTIONS","COMBOS","FUNCTIONS","FUNCTION_CALL","exceptions","when","qualifyFn","reduceRelevancy","__source_23","__lookahead_23","__concat_23","__either_23","_$xml_23","TAG_NAME_RE","XML_ENTITIES","XML_META_KEYWORDS","XML_META_PAR_KEYWORDS","APOS_META_STRING_MODE","QUOTE_META_STRING_MODE","TAG_INTERNALS","_$yaml_24","URI_CHARACTERS","CONTAINER_STRING","TIMESTAMP","VALUE_MODES","ignoreUnescapedHTML","createTabsElement","primaryElement","tabsElement","createElementFromHtml","prepend","createTab","blockElement","content","colist","selector","stopSelector","sibling","matches","append","tabElement","dataset","blockName","template","findPrimaryElement","secondaryElement","previousElementSibling","onTabClick","tabId","localStorage","setItem","getTabId","select","id","tab","addTabs","getItem","configureTabs","_$isObject_10","_$freeGlobal_4","_$root_7","_$now_13","_$trimmedEndIndex_8","_$baseTrim_3","_$getRawTag_5","__nativeObjectToString_6","_$objectToString_6","__symToStringTag_2","_$baseGetTag_2","_$isObjectLike_11","_$isSymbol_12","_$toNumber_15","nativeMin","min","_$debounce_9","lastArgs","lastThis","maxWait","timerId","lastCallTime","lastInvokeTime","leading","maxing","trailing","invokeFunc","time","leadingEdge","timerExpired","shouldInvoke","timeSinceLastCall","trailingEdge","timeWaiting","remainingWait","debounced","isInvoking","clearTimeout","cancel","flush","_$throttle_14","tocElement","toggleTocElement","contentElement","headingElements","hrefToTocAnchorElement","headingElementToTocElement","lastActiveTocElement","disableOnScroll","onLocationHashChange","updateFixedPositionClass","tocAnchorElement","get","headingElement","getHeadingElementByHref","isInViewport","activateTocElement","parentElement","onEndScroll","maxHeadingLevel","getMaxHeadingLevel","headingSelectors","headingLevel","listElement","getHeadingLevel","findHeadingElements","href","getAttribute","buildHrefToTocAnchorElement","getChildAnchorHref","buildHeadingElementToTocElement","onScroll","onResize","onTocElementClick","onToggleTocClick","activateTopHeadingTocElement","target","stopPropagation","body","documentElement","removeEventListener","computedStyle","getComputedStyle","bannerHeight","getPropertyValue","getTop","topHeadingElement","topHeadingPos","offsetTop","getTopHeading","achorElement","deactivateTocElement","scrollTop","rect","getBoundingClientRect","bottom","innerHeight","clientHeight"],"mappings":"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CL9F,UAAW,cAKbka,EAAe,CACnBla,UAAW,SACX2F,MAAO,IAAKG,IAAK,IACjBlP,SAAU,CACRkX,EAAKpI,iBACLoU,EACAE,IAGJA,EAAMpjB,SAAST,KAAK+jB,GACpB,MASMC,EAAa,CACjBxU,MAAO,SACPG,IAAK,OACLlP,SAAU,CACR,CAAE+O,MAAO,gBAAiB3F,UAAW,UACrC8N,EAAKvH,YACLuT,IAcEM,EAAgBtM,EAAK3G,QAAQ,CACjCG,OAAQ,IAZa,CACrB,OACA,OACA,MACA,KACA,MACA,MACA,OACA,OACA,QAG2B7C,KAAK,QAChCmB,UAAW,KAEPyU,EAAW,CACfra,UAAW,WACX2F,MAAO,4BACPwO,aAAa,EACbvd,SAAU,CAACkX,EAAKvL,QAAQuL,EAAKlH,WAAY,CAACjB,MAAO,gBACjDC,UAAW,GAGb,MAAO,CACLlE,KAAM,OACN2P,QAAS,CAAC,KAAM,OAChB9I,SAAU,CACRkE,SAAU,gBACVnD,QACE,+DACFgR,QACE,aACFC,SAGE,6uBAeJ3jB,SAAU,CACRwjB,EACAtM,EAAK3G,UACLkT,EACAF,EACArM,EAAKxH,kBACL2T,EACAC,EA3EkB,CACpBla,UAAW,GACX2F,MAAO,OAGW,CAClB3F,UAAW,SACX2F,MAAO,IAAKG,IAAK,KAuEfgU,GF0wFN,EG76FA,MAuBMU,GAAO,CACX,IACA,OACA,UACA,UACA,QACA,QACA,IACA,aACA,OACA,SACA,SACA,UACA,OACA,OACA,KACA,MACA,UACA,MACA,MACA,KACA,KACA,KACA,WACA,aACA,SACA,SACA,OACA,KACA,KACA,KACA,KACA,KACA,KACA,SACA,SACA,OACA,IACA,SACA,MACA,QACA,MACA,MACA,QACA,SACA,KACA,OACA,OACA,OACA,MACA,SACA,KACA,IACA,IACA,QACA,OACA,UACA,OACA,SACA,UACA,MACA,QACA,QACA,KACA,WACA,QACA,KACA,QACA,OACA,KACA,KACA,MACA,SAGIC,GAAiB,CACrB,YACA,cACA,eACA,QACA,cACA,cACA,sBACA,gBACA,eACA,eACA,gBACA,OACA,SACA,QACA,kBACA,aACA,cACA,iBACA,kBACA,UACA,uBACA,mBACA,yBACA,+BACA,aACA,OACA,YACA,SACA,QAEA,YACA,YACA,aACA,cAIIC,GAAiB,CACrB,SACA,WACA,QACA,UACA,UACA,UACA,UACA,MACA,WACA,OACA,QACA,UACA,QACA,cACA,gBACA,aACA,SACA,QACA,gBACA,eACA,MACA,OACA,eACA,QACA,gBACA,WACA,UACA,KACA,OACA,aACA,eACA,OACA,OACA,aACA,MACA,YACA,UACA,iBACA,eACA,mBACA,cACA,aACA,eACA,WACA,eACA,OACA,oBACA,YACA,aACA,WACA,QACA,OACA,QACA,SACA,gBACA,eACA,QACA,UACA,SAIIC,GAAkB,CACtB,QACA,WACA,SACA,MACA,aACA,eACA,aACA,gBACA,SACA,OACA,cACA,YACA,UACA,kBAGIC,GAAa,CACjB,gBACA,cACA,aACA,YACA,kBACA,sBACA,qBACA,sBACA,4BACA,iBACA,uBACA,4BACA,OACA,sBACA,aACA,wBACA,kBACA,mBACA,mBACA,oBACA,sBACA,oBACA,kBACA,SACA,gBACA,sBACA,4BACA,6BACA,sBACA,sBACA,kBACA,eACA,eACA,sBACA,sBACA,qBACA,sBACA,qBACA,cACA,oBACA,oBACA,oBACA,gBACA,eACA,qBACA,qBACA,qBACA,iBACA,eACA,aACA,mBACA,yBACA,0BACA,mBACA,mBACA,eACA,SACA,uBACA,aACA,aACA,cACA,eACA,eACA,eACA,QACA,OACA,YACA,QACA,eACA,cACA,aACA,cACA,oBACA,oBACA,oBACA,cACA,eACA,UACA,UACA,oBACA,gBACA,SACA,YACA,UACA,cACA,SACA,OACA,aACA,iBACA,YACA,YACA,cACA,YACA,QACA,OACA,eACA,cACA,wBACA,eACA,yBACA,YACA,mBACA,iBACA,eACA,aACA,eACA,yBACA,0BACA,cACA,SACA,UACA,OACA,oBACA,kBACA,mBACA,WACA,UACA,UACA,kBACA,OACA,iBACA,cACA,aACA,mBACA,sBACA,kBACA,SACA,gBACA,cACA,eACA,aACA,QACA,OACA,aACA,YACA,aACA,YACA,WACA,YACA,WACA,YACA,SACA,OACA,SACA,aACA,kBACA,UACA,QACA,UACA,UACA,gBACA,iBACA,gBACA,gBACA,WACA,gBACA,aACA,aACA,UACA,iBACA,eACA,gBACA,cACA,mBACA,oBACA,oBACA,cACA,qBACA,iBACA,WACA,SACA,SACA,QACA,MACA,WACA,eACA,aACA,kBACA,kBACA,wBACA,uBACA,wBACA,cACA,gBACA,iBACA,cACA,iBACA,0BACA,MACA,YACA,mBACA,kBACA,aACA,mBACA,sBACA,sBACA,6BACA,eACA,iBACA,aACA,cACA,SACA,QACA,aACA,eACA,YACA,WAGAxK,UAsBF,SAASyK,GAAU1V,GACjB,OAOF,YAAmBhO,GAEjB,OADeA,EAAKoQ,KAAKC,GApB3B,SAAgBrC,GACd,OAAKA,EACa,iBAAPA,EAAwBA,EAE5BA,EAAGD,OAHM,IHq7FlB,CGl6FiC4V,CAAOtT,KAAI/C,KAAK,GHm7FjD,CG37FSsW,CAAO,MAAO5V,EAAI,IHk7F3B,CGpxFA,IAAA6V,GA3IA,SAAalN,GACX,MAAMmN,EArdM,CAACnN,IACN,CACLoN,UAAW,CACTlb,UAAW,OACX2F,MAAO,cAETwV,SAAU,CACRnb,UAAW,SACX2F,MAAO,oCAETyV,wBAAyB,CACvBpb,UAAW,gBACX2F,MAAO,KACPG,IAAK,KACLC,QAAS,IACTnP,SAAU,CACRkX,EAAKjI,iBACLiI,EAAK9H,sBAocGqV,CAAMvN,GAWdwN,EAAU,CACdxN,EAAKjI,iBACLiI,EAAK9H,mBAGP,MAAO,CACLtE,KAAM,MACNsI,kBAAkB,EAClBjE,QAAS,UACTwC,SAAU,CACRgT,iBAAkB,WAEpBpP,iBAAkB,CAGhBoP,iBAAkB,gBAEpB3kB,SAAU,CACRkX,EAAKzH,qBAxBa,CACpBV,MAAO,gCA2BLmI,EAAKpH,gBACL,CACE1G,UAAW,cACX2F,MAAO,kBACPC,UAAW,GAEb,CACE5F,UAAW,iBACX2F,MAAO,6BACPC,U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,EAAKzH,uBAGT6V,EACAc,GV2iIN,EW1tIA,MAAMC,GAAW,2BACXF,GAAW,CACf,KACA,KACA,KACA,KACA,MACA,QACA,UACA,MACA,MACA,WACA,KACA,SACA,OACA,OACA,QACA,QACA,aACA,OACA,QACA,OACA,UACA,MACA,SACA,WACA,SACA,SACA,MACA,QACA,QACA,QAIA,WACA,QACA,QACA,SACA,SACA,OACA,SACA,WAEIG,GAAW,CACf,OACA,QACA,OACA,YACA,MACA,YAoFIC,GAAY,GAAG1V,OAlCI,CACvB,cACA,aACA,gBACA,eAEA,UACA,UAEA,OACA,WACA,QACA,aACA,WACA,YACA,qBACA,YACA,qBACA,SACA,YAGyB,CACzB,YACA,OACA,QACA,UACA,SACA,WACA,eACA,SACA,UA9EY,CACZ,OACA,WACA,SACA,OACA,OACA,SACA,SACA,SACA,WACA,UACA,QACA,SACA,MACA,MACA,UACA,UACA,QACA,UACA,OACA,UACA,eACA,aACA,aACA,YACA,cACA,cACA,eACA,QACA,aACA,oBACA,cACA,gBACA,iBACA,UAGkB,CAClB,YACA,gBACA,aACA,iBACA,cACA,YACA,aAgEF,SAAS2V,GAAUjY,GACjB,OAAOkY,GAAO,MAAOlY,EAAI,IX+tI3B,CWxtIA,SAASkY,MAAUlmB,GAEjB,OADeA,EAAKoQ,KAAKC,IAAM8V,OApBjBnY,EAoBwBqC,GAlBpB,iBAAPrC,EAAwBA,EAE5BA,EAAGD,OAHM,KADlB,IAAgBC,CAoB0B,IAAEV,KAAK,GXguIjD,CW/yHA,IAAA8Y,GAraA,SAAoBzP,GAQlB,MAMM0P,EAAaP,GACbQ,EACG,KADHA,EAEC,MAEDC,EAAU,CACd/X,MAAO,sBACPG,IAAK,4BAKL6X,kBAAmB,CAAC3V,EAAOC,KACzB,MAAM2V,EAAkB5V,EAAM,GAAGpQ,OAASoQ,EAAM3P,MAC1CwlB,EAAW7V,EAAME,MAAM0V,GAIZ,MAAbC,EAMa,MAAbA,IA9Bc,EAAC7V,GAAS8V,YAC9B,MAAMhkB,EAAM,KAAOkO,EAAM,GAAG5K,MAAM,GAElC,OAAgB,IADJ4K,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W,SACX2F,MAAO,uBAmEL6c,EACAG,EACAD,EACA5U,EAAKtH,cA5HU,CACjBxG,UAAW,OACX2F,MAAO,enBi4MX,EoB/2MA,IAAAid,GApBA,SAAe9U,GACb,MAAO,CACLpM,KAAM,gBACN2P,QAAS,CAAE,WACXza,SAAU,CACR,CACEoJ,UAAW,OAIX2F,MAAO,iCACP4H,OAAQ,CACNzH,IAAK,gBACL8M,YAAa,UpBq5MvB,EqBl6MA,SAASiQ,GAAO1d,GACd,OAAKA,EACa,iBAAPA,EAAwBA,EAE5BA,EAAGD,OAHM,IrBm7MlB,CqBz6MA,SAAS4d,MAAU3rB,GAEjB,OADeA,EAAKoQ,KAAKC,GAAMqb,GAAOrb,KAAI/C,KAAK,GrBi7MjD,CqBt6MA,SAASse,MAAU5rB,GAEjB,MADe,IAAMA,EAAKoQ,KAAKC,GAAMqb,GAAOrb,KAAI/C,KAAK,KAAO,GrBi7M9D,CqBxxLA,IAAAue,GA/oBA,SAAalV,GACX,MAAMmV,EAAenV,EAAK5H,QAAQ,KAAM,KAmBlCgX,EAAW,CACf,OACA,QAGA,WAUI2B,EAAQ,CACZ,SACA,SACA,OACA,UACA,OACA,YACA,OACA,OACA,MACA,WACA,UACA,QACA,MACA,UACA,WACA,QACA,QACA,WACA,UACA,OACA,MACA,WACA,OACA,YACA,UACA,UACA,aAmYIqE,EAAqB,CACzB,MACA,OACA,YACA,OACA,OACA,MACA,OACA,OACA,UACA,WACA,OACA,MACA,OACA,QACA,YACA,aACA,YACA,aACA,QACA,UACA,MACA,UACA,cACA,QACA,aACA,gBACA,cACA,cACA,iBACA,aACA,aACA,uBACA,aACA,MACA,aACA,OACA,UACA,KACA,MACA,QACA,QACA,MACA,MACA,MACA,YACA,QACA,SACA,eACA,kBACA,kBACA,WACA,iBACA,QACA,OACA,YACA,YACA,aACA,iBACA,UACA,aACA,WACA,WACA,WACA,aACA,MACA,OACA,OACA,aACA,cACA,YACA,kBACA,MACA,MACA,OACA,YACA,kBACA,QACA,OACA,aACA,SACA,QACA,WACA,UACA,WACA,gBAwBIC,EAAS,CACb,eACA,cACA,cACA,cACA,WACA,cACA,iBACA,gBACA,cACA,gBACA,gBACA,eACA,cACA,aACA,cACA,iBAGIC,EAAYF,EAEZnG,EAAW,CArff,MACA,OACA,MACA,WACA,QACA,MACA,MACA,MACA,QACA,YACA,wBACA,KACA,aACA,OACA,aACA,KACA,OACA,SACA,gBACA,MACA,QACA,cACA,kBACA,UACA,SACA,SACA,OACA,UACA,OACA,KACA,OACA,SACA,cACA,WACA,OACA,OACA,OACA,UACA,OACA,cACA,YACA,mBACA,QACA,aACA,OACA,QACA,WACA,UACA,UACA,SACA,SACA,YACA,UACA,aACA,WACA,UACA,OACA,OACA,gBACA,MACA,OACA,QACA,YACA,aACA,SACA,QACA,OACA,YACA,UACA,kBACA,eACA,kCACA,eACA,eACA,cACA,iBACA,eACA,oBACA,eACA,eACA,mCACA,eACA,SACA,QACA,OACA,MACA,aACA,MACA,UACA,WACA,UACA,UACA,SACA,SACA,aACA,QACA,WACA,gBACA,aACA,WACA,SACA,OACA,UACA,OACA,UACA,OACA,QACA,MACA,YACA,gBACA,WACA,SACA,SACA,QACA,SACA,OACA,UACA,SACA,MACA,WACA,UACA,QACA,QACA,SACA,cACA,QACA,QACA,MACA,UACA,YACA,OACA,OACA,OACA,WACA,SACA,MACA,SACA,QACA,QACA,WACA,SACA,SACA,OACA,OACA,WACA,KACA,YACA,UACA,QACA,QACA,cACA,SACA,MACA,UACA,YACA,eACA,WACA,OACA,KACA,OACA,aACA,gBACA,cACA,cACA,iBACA,aACA,aACA,uBACA,aACA,MACA,WACA,QACA,aACA,UACA,OACA,UACA,OACA,OACA,aACA,UACA,KACA,QACA,YACA,iBACA,MACA,QACA,QACA,QACA,eACA,kBACA,UACA,MACA,SACA,QACA,SACA,MACA,SACA,MACA,WACA,SACA,QACA,WACA,WACA,UACA,QACA,QACA,MACA,KACA,OACA,YACA,MACA,YACA,QACA,OACA,SACA,UACA,eACA,oBACA,KACA,SACA,MACA,OACA,KACA,MACA,OACA,OACA,KACA,QACA,MACA,QACA,OACA,WACA,UACA,YACA,YACA,UACA,MACA,UACA,eACA,kBACA,kBACA,SACA,UACA,WACA,iBACA,QACA,WACA,YACA,UACA,UACA,YACA,MACA,QACA,OACA,QACA,OACA,YACA,MACA,aACA,cACA,YACA,YACA,aACA,iBACA,UACA,aACA,WACA,WACA,WACA,UACA,SACA,SACA,UACA,SACA,QACA,WACA,SACA,MACA,aACA,OACA,UACA,YACA,QACA,SACA,SACA,SACA,OACA,SACA,YACA,eACA,MACA,OACA,UACA,MACA,OACA,OACA,WACA,OACA,WACA,eACA,MACA,eACA,WACA,aACA,OACA,QACA,SACA,aACA,cACA,cACA,SACA,YACA,kBACA,WACA,MACA,YACA,SACA,cACA,cACA,QACA,cACA,MACA,OACA,OACA,OACA,YACA,gBACA,kBACA,KACA,WACA,YACA,kBACA,cACA,QACA,UACA,OACA,aACA,OACA,WACA,UACA,QACA,SACA,UACA,SACA,YACA,QACA,OACA,QACA,QACA,SACA,WACA,UACA,WACA,YACA,UACA,UACA,aACA,OACA,WACA,QACA,eACA,SACA,OACA,SACA,UACA,OAzXA,MACA,MACA,YACA,OACA,QACA,QACA,OACA,QA0f0DhH,QAAQzM,IAC1D4Z,EAAmBjtB,SAASqT,KAchC+Z,EAAgB,CACpB1d,MAAOmd,GAAO,KAAMC,MAAUK,GAAY,SAC1C7a,SAAU,CACRgS,SAAU6I,IAmBd,MAAO,CACL1hB,KAAM,MACNsI,kBAAkB,EAElBjE,QAAS,WACTwC,SAAU,CACRkE,SAAU,YACVnD,QArBJ,SAAyB0L,GAAMsO,WAACA,EAAUC,KAAEA,GAAQ,CAAA,GAClD,MAAMC,EAAYD,EAElB,OADAD,EAAaA,GAAc,GACpBtO,EAAKzN,KAAK4N,GACXA,EAAKnN,MAAM,WAAasb,EAAWrtB,SAASkf,GACvCA,EACEqO,EAAUrO,GACZ,GAAGA,MAEHA,G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","file":"site.js","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(function () {\n \"use strict\";\n\n window.addEventListener(\"load\", onChange);\n window.addEventListener(\"hashchange\", onChange);\n\n function onChange() {\n const element = document.getElementById(\"anchor-rewrite\");\n const anchor = window.location.hash.substr(1);\n if (element && anchor) {\n const rewites = JSON.parse(element.innerHTML);\n updateAnchor(anchor, rewites);\n }\n }\n\n function updateAnchor(anchor, rewrites) {\n const seen = [anchor];\n console.debug(anchor);\n while (rewrites[anchor]) {\n anchor = rewrites[anchor];\n if (seen.includes(anchor)) {\n console.error(\"Skipping circular anchor update\");\n return;\n }\n seen.push(anchor);\n }\n window.location.hash = anchor;\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(function () {\n \"use strict\";\n\n window.addEventListener(\"load\", onChange);\n window.addEventListener(\"hashchange\", onChange);\n\n function onChange() {\n const element = document.getElementById(\"anchor-rewrite\");\n const anchor = window.location.hash.substr(1);\n if (element && anchor) {\n const rewites = JSON.parse(element.innerHTML);\n updateAnchor(anchor, rewites);\n }\n }\n\n function updateAnchor(anchor, rewrites) {\n const seen = [anchor];\n console.debug(anchor);\n while (rewrites[anchor]) {\n anchor = rewrites[anchor];\n if (seen.includes(anchor)) {\n console.error(\"Skipping circular anchor update\");\n return;\n }\n seen.push(anchor);\n }\n window.location.hash = anchor;\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(function () {\n \"use strict\";\n\n markLastAuthor();\n\n function markLastAuthor() {\n let candidate = document.getElementById(\"author\");\n let lastAuthorElement = candidate;\n while (candidate) {\n if (candidate.classList.contains(\"author\")) {\n lastAuthorElement = candidate;\n }\n candidate = candidate.nextElementSibling;\n }\n if (lastAuthorElement) {\n lastAuthorElement.classList.add(\"last-author\");\n }\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(function () {\n \"use strict\";\n\n markLastAuthor();\n\n function markLastAuthor() {\n let candidate = document.getElementById(\"author\");\n let lastAuthorElement = candidate;\n while (candidate) {\n if (candidate.classList.contains(\"author\")) {\n lastAuthorElement = candidate;\n }\n candidate = candidate.nextElementSibling;\n }\n if (lastAuthorElement) {\n lastAuthorElement.classList.add(\"last-author\");\n }\n }\n})();\n","(function(){\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\nfunction baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n}\n\nmodule.exports = baseDelay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n addCodeToolElements();\n\n function addCodeToolElements() {\n for (const preElement of document.querySelectorAll(\".doc pre.highlight\")) {\n const codeToolsElement = document.createElement(\"div\");\n codeToolsElement.className = \"codetools\";\n if (addButtons(preElement, codeToolsElement)) {\n preElement.appendChild(codeToolsElement);\n }\n }\n\n function addButtons(preElement, codeToolsElement) {\n let numberOfButtons = 0;\n if (hasHideWhenFoldedSpans(preElement)) {\n addFoldUnfoldButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n if (window.navigator.clipboard) {\n addCopyButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n return numberOfButtons > 0;\n }\n\n function hasHideWhenFoldedSpans(preElement) {\n return !!preElement.querySelector(\"span.hide-when-folded\");\n }\n\n function addFoldUnfoldButton(preElement, codeToolsElement) {\n const foldUnfoldButton = createButton();\n updateFoldUnfoldButton(foldUnfoldButton, true);\n foldUnfoldButton.addEventListener(\n \"click\",\n onFoldUnfoldButtonClick.bind(foldUnfoldButton, preElement)\n );\n codeToolsElement.appendChild(foldUnfoldButton);\n }\n\n function addCopyButton(preElement, codeToolsElement) {\n const copyButton = createButton(\"Copy to clipboard\", \"copy-button\");\n copyButton.addEventListener(\n \"click\",\n onCopyButtonClick.bind(copyButton, preElement)\n );\n copyButton.addEventListener(\"mouseleave\", clearClicked.bind(copyButton));\n copyButton.addEventListener(\"blur\", clearClicked.bind(copyButton));\n const copiedPopup = document.createElement(\"span\");\n copyButton.appendChild(copiedPopup);\n copiedPopup.className = \"copied\";\n codeToolsElement.appendChild(copyButton);\n }\n\n function createButton(label, className) {\n const buttonElement = document.createElement(\"button\");\n buttonElement.className = className;\n buttonElement.title = label;\n buttonElement.type = \"button\";\n const labelElement = document.createElement(\"span\");\n labelElement.appendChild(document.createTextNode(label));\n labelElement.className = \"label\";\n buttonElement.appendChild(labelElement);\n return buttonElement;\n }\n }\n\n function onCopyButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const copy = codeElement.cloneNode(true);\n for (const hideWhenFoldedElement of copy.querySelectorAll(\n \".hide-when-unfolded\"\n )) {\n hideWhenFoldedElement.parentNode.removeChild(hideWhenFoldedElement);\n }\n const text = copy.innerText;\n if (text) {\n window.navigator.clipboard\n .writeText(text + \"\\n\")\n .then(markClicked.bind(this));\n }\n }\n\n function markClicked() {\n this.classList.add(\"clicked\");\n }\n\n function clearClicked() {\n this.classList.remove(\"clicked\");\n }\n\n function onFoldUnfoldButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const unfolding = !codeElement.classList.contains(\"unfolded\");\n codeElement.classList.remove(unfolding ? \"folding\" : \"unfolding\");\n codeElement.classList.add(unfolding ? \"unfolding\" : \"folding\");\n delay(function () {\n codeElement.classList.remove(unfolding ? \"unfolding\" : \"folding\");\n codeElement.classList.toggle(\"unfolded\");\n }, 1100);\n updateFoldUnfoldButton(this, !unfolding);\n }\n\n function updateFoldUnfoldButton(button, unfold) {\n const label = unfold ? \"Expand folded text\" : \"Collapse foldable text\";\n button.classList.remove(unfold ? \"fold-button\" : \"unfold-button\");\n button.classList.add(unfold ? \"unfold-button\" : \"fold-button\");\n button.querySelector(\"span.label\").innerText = label;\n button.title = label;\n }\n})();\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n","var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","var baseDelay = require('./_baseDelay'),\n baseRest = require('./_baseRest'),\n toNumber = require('./toNumber');\n\n/**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\nvar delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n});\n\nmodule.exports = delay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n addCodeToolElements();\n\n function addCodeToolElements() {\n for (const preElement of document.querySelectorAll(\".doc pre.highlight\")) {\n const codeToolsElement = document.createElement(\"div\");\n codeToolsElement.className = \"codetools\";\n if (addButtons(preElement, codeToolsElement)) {\n preElement.appendChild(codeToolsElement);\n }\n }\n\n function addButtons(preElement, codeToolsElement) {\n let numberOfButtons = 0;\n if (hasHideWhenFoldedSpans(preElement)) {\n addFoldUnfoldButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n if (window.navigator.clipboard) {\n addCopyButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n return numberOfButtons > 0;\n }\n\n function hasHideWhenFoldedSpans(preElement) {\n return !!preElement.querySelector(\"span.hide-when-folded\");\n }\n\n function addFoldUnfoldButton(preElement, codeToolsElement) {\n const foldUnfoldButton = createButton();\n updateFoldUnfoldButton(foldUnfoldButton, true);\n foldUnfoldButton.addEventListener(\n \"click\",\n onFoldUnfoldButtonClick.bind(foldUnfoldButton, preElement)\n );\n codeToolsElement.appendChild(foldUnfoldButton);\n }\n\n function addCopyButton(preElement, codeToolsElement) {\n const copyButton = createButton(\"Copy to clipboard\", \"copy-button\");\n copyButton.addEventListener(\n \"click\",\n onCopyButtonClick.bind(copyButton, preElement)\n );\n copyButton.addEventListener(\"mouseleave\", clearClicked.bind(copyButton));\n copyButton.addEventListener(\"blur\", clearClicked.bind(copyButton));\n const copiedPopup = document.createElement(\"span\");\n copyButton.appendChild(copiedPopup);\n copiedPopup.className = \"copied\";\n codeToolsElement.appendChild(copyButton);\n }\n\n function createButton(label, className) {\n const buttonElement = document.createElement(\"button\");\n buttonElement.className = className;\n buttonElement.title = label;\n buttonElement.type = \"button\";\n const labelElement = document.createElement(\"span\");\n labelElement.appendChild(document.createTextNode(label));\n labelElement.className = \"label\";\n buttonElement.appendChild(labelElement);\n return buttonElement;\n }\n }\n\n function onCopyButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const copy = codeElement.cloneNode(true);\n for (const hideWhenFoldedElement of copy.querySelectorAll(\n \".hide-when-unfolded\"\n )) {\n hideWhenFoldedElement.parentNode.removeChild(hideWhenFoldedElement);\n }\n const text = copy.innerText;\n if (text) {\n window.navigator.clipboard\n .writeText(text + \"\\n\")\n .then(markClicked.bind(this));\n }\n }\n\n function markClicked() {\n this.classList.add(\"clicked\");\n }\n\n function clearClicked() {\n this.classList.remove(\"clicked\");\n }\n\n function onFoldUnfoldButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const unfolding = !codeElement.classList.contains(\"unfolded\");\n codeElement.classList.remove(unfolding ? \"folding\" : \"unfolding\");\n codeElement.classList.add(unfolding ? \"unfolding\" : \"folding\");\n delay(function () {\n codeElement.classList.remove(unfolding ? \"unfolding\" : \"folding\");\n codeElement.classList.toggle(\"unfolded\");\n }, 1100);\n updateFoldUnfoldButton(this, !unfolding);\n }\n\n function updateFoldUnfoldButton(button, unfold) {\n const label = unfold ? \"Expand folded text\" : \"Collapse foldable text\";\n button.classList.remove(unfold ? \"fold-button\" : \"unfold-button\");\n button.classList.add(unfold ? \"unfold-button\" : \"fold-button\");\n button.querySelector(\"span.label\").innerText = label;\n button.title = label;\n }\n})();\n","\n}());","function deepFreeze(obj) {\n if (obj instanceof Map) {\n obj.clear = obj.delete = obj.set = function () {\n throw new Error('map is read-only');\n };\n } else if (obj instanceof Set) {\n obj.add = obj.clear = obj.delete = function () {\n throw new Error('set is read-only');\n };\n }\n\n // Freeze self\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach(function (name) {\n var prop = obj[name];\n\n // Freeze prop if it is an object\n if (typeof prop == 'object' && !Object.isFrozen(prop)) {\n deepFreeze(prop);\n }\n });\n\n return obj;\n}\n\nvar deepFreezeEs6 = deepFreeze;\nvar _default = deepFreeze;\ndeepFreezeEs6.default = _default;\n\n/** @implements CallbackResponse */\nclass Response {\n /**\n * @param {CompiledMode} mode\n */\n constructor(mode) {\n // eslint-disable-next-line no-undefined\n if (mode.data === undefined) mode.data = {};\n\n this.data = mode.data;\n this.isMatchIgnored = false;\n }\n\n ignoreMatch() {\n this.isMatchIgnored = true;\n }\n}\n\n/**\n * @param {string} value\n * @returns {string}\n */\nfunction escapeHTML(value) {\n return value\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * performs a shallow merge of multiple objects into one\n *\n * @template T\n * @param {T} original\n * @param {Record[]} objects\n * @returns {T} a single new object\n */\nfunction inherit(original, ...objects) {\n /** @type Record */\n const result = Object.create(null);\n\n for (const key in original) {\n result[key] = original[key];\n }\n objects.forEach(function(obj) {\n for (const key in obj) {\n result[key] = obj[key];\n }\n });\n return /** @type {T} */ (result);\n}\n\n/**\n * @typedef {object} Renderer\n * @property {(text: string) => void} addText\n * @property {(node: Node) => void} openNode\n * @property {(node: Node) => void} closeNode\n * @property {() => string} value\n */\n\n/** @typedef {{kind?: string, sublanguage?: boolean}} Node */\n/** @typedef {{walk: (r: Renderer) => void}} Tree */\n/** */\n\nconst SPAN_CLOSE = '
';\n\n/**\n * Determines if a node needs to be wrapped in \n *\n * @param {Node} node */\nconst emitsWrappingTags = (node) => {\n return !!node.kind;\n};\n\n/** @type {Renderer} */\nclass HTMLRenderer {\n /**\n * Creates a new HTMLRenderer\n *\n * @param {Tree} parseTree - the parse tree (must support `walk` API)\n * @param {{classPrefix: string}} options\n */\n constructor(parseTree, options) {\n this.buffer = \"\";\n this.classPrefix = options.classPrefix;\n parseTree.walk(this);\n }\n\n /**\n * Adds texts to the output stream\n *\n * @param {string} text */\n addText(text) {\n this.buffer += escapeHTML(text);\n }\n\n /**\n * Adds a node open to the output stream (if needed)\n *\n * @param {Node} node */\n openNode(node) {\n if (!emitsWrappingTags(node)) return;\n\n let className = node.kind;\n if (!node.sublanguage) {\n className = `${this.classPrefix}${className}`;\n }\n this.span(className);\n }\n\n /**\n * Adds a node close to the output stream (if needed)\n *\n * @param {Node} node */\n closeNode(node) {\n if (!emitsWrappingTags(node)) return;\n\n this.buffer += SPAN_CLOSE;\n }\n\n /**\n * returns the accumulated buffer\n */\n value() {\n return this.buffer;\n }\n\n // helpers\n\n /**\n * Builds a span element\n *\n * @param {string} className */\n span(className) {\n this.buffer += ``;\n }\n}\n\n/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} | string} Node */\n/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} } DataNode */\n/** */\n\nclass TokenTree {\n constructor() {\n /** @type DataNode */\n this.rootNode = { children: [] };\n this.stack = [this.rootNode];\n }\n\n get top() {\n return this.stack[this.stack.length - 1];\n }\n\n get root() { return this.rootNode; }\n\n /** @param {Node} node */\n add(node) {\n this.top.children.push(node);\n }\n\n /** @param {string} kind */\n openNode(kind) {\n /** @type Node */\n const node = { kind, children: [] };\n this.add(node);\n this.stack.push(node);\n }\n\n closeNode() {\n if (this.stack.length > 1) {\n return this.stack.pop();\n }\n // eslint-disable-next-line no-undefined\n return undefined;\n }\n\n closeAllNodes() {\n while (this.closeNode());\n }\n\n toJSON() {\n return JSON.stringify(this.rootNode, null, 4);\n }\n\n /**\n * @typedef { import(\"./html_renderer\").Renderer } Renderer\n * @param {Renderer} builder\n */\n walk(builder) {\n // this does not\n return this.constructor._walk(builder, this.rootNode);\n // this works\n // return TokenTree._walk(builder, this.rootNode);\n }\n\n /**\n * @param {Renderer} builder\n * @param {Node} node\n */\n static _walk(builder, node) {\n if (typeof node === \"string\") {\n builder.addText(node);\n } else if (node.children) {\n builder.openNode(node);\n node.children.forEach((child) => this._walk(builder, child));\n builder.closeNode(node);\n }\n return builder;\n }\n\n /**\n * @param {Node} node\n */\n static _collapse(node) {\n if (typeof node === \"string\") return;\n if (!node.children) return;\n\n if (node.children.every(el => typeof el === \"string\")) {\n // node.text = node.children.join(\"\");\n // delete node.children;\n node.children = [node.children.join(\"\")];\n } else {\n node.children.forEach((child) => {\n TokenTree._collapse(child);\n });\n }\n }\n}\n\n/**\n Currently this is all private API, but this is the minimal API necessary\n that an Emitter must implement to fully support the parser.\n\n Minimal interface:\n\n - addKeyword(text, kind)\n - addText(text)\n - addSublanguage(emitter, subLanguageName)\n - finalize()\n - openNode(kind)\n - closeNode()\n - closeAllNodes()\n - toHTML()\n\n*/\n\n/**\n * @implements {Emitter}\n */\nclass TokenTreeEmitter extends TokenTree {\n /**\n * @param {*} options\n */\n constructor(options) {\n super();\n this.options = options;\n }\n\n /**\n * @param {string} text\n * @param {string} kind\n */\n addKeyword(text, kind) {\n if (text === \"\") { return; }\n\n this.openNode(kind);\n this.addText(text);\n this.closeNode();\n }\n\n /**\n * @param {string} text\n */\n addText(text) {\n if (text === \"\") { return; }\n\n this.add(text);\n }\n\n /**\n * @param {Emitter & {root: DataNode}} emitter\n * @param {string} name\n */\n addSublanguage(emitter, name) {\n /** @type DataNode */\n const node = emitter.root;\n node.kind = name;\n node.sublanguage = true;\n this.add(node);\n }\n\n toHTML() {\n const renderer = new HTMLRenderer(this, this.options);\n return renderer.value();\n }\n\n finalize() {\n return true;\n }\n}\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\nfunction escape(value) {\n return new RegExp(value.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&'), 'm');\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n if (!re) return null;\n if (typeof re === \"string\") return re;\n\n return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n const joined = args.map((x) => source(x)).join(\"\");\n return joined;\n}\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] } args\n * @returns {string}\n */\nfunction either(...args) {\n const joined = '(' + args.map((x) => source(x)).join(\"|\") + \")\";\n return joined;\n}\n\n/**\n * @param {RegExp} re\n * @returns {number}\n */\nfunction countMatchGroups(re) {\n return (new RegExp(re.toString() + '|')).exec('').length - 1;\n}\n\n/**\n * Does lexeme start with a regular expression match at the beginning\n * @param {RegExp} re\n * @param {string} lexeme\n */\nfunction startsWith(re, lexeme) {\n const match = re && re.exec(lexeme);\n return match && match.index === 0;\n}\n\n// BACKREF_RE matches an open parenthesis or backreference. To avoid\n// an incorrect parse, it additionally matches the following:\n// - [...] elements, where the meaning of parentheses and escapes change\n// - other escape sequences, so we do not misparse escape sequences as\n// interesting elements\n// - non-matching or lookahead parentheses, which do not capture. These\n// follow the '(' with a '?'.\nconst BACKREF_RE = /\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./;\n\n// join logically computes regexps.join(separator), but fixes the\n// backreferences so they continue to match.\n// it also places each individual regular expression into it's own\n// match group, keeping track of the sequencing of those match groups\n// is currently an exercise for the caller. :-)\n/**\n * @param {(string | RegExp)[]} regexps\n * @param {string} separator\n * @returns {string}\n */\nfunction join(regexps, separator = \"|\") {\n let numCaptures = 0;\n\n return regexps.map((regex) => {\n numCaptures += 1;\n const offset = numCaptures;\n let re = source(regex);\n let out = '';\n\n while (re.length > 0) {\n const match = BACKREF_RE.exec(re);\n if (!match) {\n out += re;\n break;\n }\n out += re.substring(0, match.index);\n re = re.substring(match.index + match[0].length);\n if (match[0][0] === '\\\\' && match[1]) {\n // Adjust the backreference.\n out += '\\\\' + String(Number(match[1]) + offset);\n } else {\n out += match[0];\n if (match[0] === '(') {\n numCaptures++;\n }\n }\n }\n return out;\n }).map(re => `(${re})`).join(separator);\n}\n\n// Common regexps\nconst MATCH_NOTHING_RE = /\\b\\B/;\nconst IDENT_RE = '[a-zA-Z]\\\\w*';\nconst UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\\\w*';\nconst NUMBER_RE = '\\\\b\\\\d+(\\\\.\\\\d+)?';\nconst C_NUMBER_RE = '(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)'; // 0x..., 0..., decimal, float\nconst BINARY_NUMBER_RE = '\\\\b(0b[01]+)'; // 0b...\nconst RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~';\n\n/**\n* @param { Partial & {binary?: string | RegExp} } opts\n*/\nconst SHEBANG = (opts = {}) => {\n const beginShebang = /^#![ ]*\\//;\n if (opts.binary) {\n opts.begin = concat(\n beginShebang,\n /.*\\b/,\n opts.binary,\n /\\b.*/);\n }\n return inherit({\n className: 'meta',\n begin: beginShebang,\n end: /$/,\n relevance: 0,\n /** @type {ModeCallback} */\n \"on:begin\": (m, resp) => {\n if (m.index !== 0) resp.ignoreMatch();\n }\n }, opts);\n};\n\n// Common modes\nconst BACKSLASH_ESCAPE = {\n begin: '\\\\\\\\[\\\\s\\\\S]', relevance: 0\n};\nconst APOS_STRING_MODE = {\n className: 'string',\n begin: '\\'',\n end: '\\'',\n illegal: '\\\\n',\n contains: [BACKSLASH_ESCAPE]\n};\nconst QUOTE_STRING_MODE = {\n className: 'string',\n begin: '\"',\n end: '\"',\n illegal: '\\\\n',\n contains: [BACKSLASH_ESCAPE]\n};\nconst PHRASAL_WORDS_MODE = {\n 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};\n/**\n * Creates a comment mode\n *\n * @param {string | RegExp} begin\n * @param {string | RegExp} end\n * @param {Mode | {}} [modeOptions]\n * @returns {Partial}\n */\nconst COMMENT = function(begin, end, modeOptions = {}) {\n const mode = inherit(\n {\n className: 'comment',\n begin,\n end,\n contains: []\n },\n modeOptions\n );\n mode.contains.push(PHRASAL_WORDS_MODE);\n mode.contains.push({\n className: 'doctag',\n begin: '(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):',\n relevance: 0\n });\n return mode;\n};\nconst C_LINE_COMMENT_MODE = COMMENT('//', '$');\nconst C_BLOCK_COMMENT_MODE = COMMENT('/\\\\*', '\\\\*/');\nconst HASH_COMMENT_MODE = COMMENT('#', '$');\nconst NUMBER_MODE = {\n className: 'number',\n begin: NUMBER_RE,\n relevance: 0\n};\nconst C_NUMBER_MODE = {\n className: 'number',\n begin: C_NUMBER_RE,\n relevance: 0\n};\nconst BINARY_NUMBER_MODE = {\n className: 'number',\n begin: BINARY_NUMBER_RE,\n relevance: 0\n};\nconst CSS_NUMBER_MODE = {\n className: 'number',\n begin: NUMBER_RE + '(' +\n '%|em|ex|ch|rem' +\n '|vw|vh|vmin|vmax' +\n '|cm|mm|in|pt|pc|px' +\n '|deg|grad|rad|turn' +\n '|s|ms' +\n '|Hz|kHz' +\n '|dpi|dpcm|dppx' +\n ')?',\n relevance: 0\n};\nconst REGEXP_MODE = {\n // this outer rule makes sure we actually have a WHOLE regex and not simply\n // an expression such as:\n //\n // 3 / something\n //\n // (which will then blow up when regex's `illegal` sees the newline)\n begin: /(?=\\/[^/\\n]*\\/)/,\n contains: [{\n className: 'regexp',\n begin: /\\//,\n end: /\\/[gimuy]*/,\n illegal: /\\n/,\n contains: [\n BACKSLASH_ESCAPE,\n {\n begin: /\\[/,\n end: /\\]/,\n relevance: 0,\n contains: [BACKSLASH_ESCAPE]\n }\n ]\n }]\n};\nconst TITLE_MODE = {\n className: 'title',\n begin: IDENT_RE,\n relevance: 0\n};\nconst UNDERSCORE_TITLE_MODE = {\n className: 'title',\n begin: UNDERSCORE_IDENT_RE,\n relevance: 0\n};\nconst METHOD_GUARD = {\n // excludes method names from keyword processing\n begin: '\\\\.\\\\s*' + UNDERSCORE_IDENT_RE,\n relevance: 0\n};\n\n/**\n * Adds end same as begin mechanics to a mode\n *\n * Your mode must include at least a single () match group as that first match\n * group is what is used for comparison\n * @param {Partial} mode\n */\nconst END_SAME_AS_BEGIN = function(mode) {\n return Object.assign(mode,\n {\n /** @type {ModeCallback} */\n 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },\n /** @type {ModeCallback} */\n 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }\n });\n};\n\nvar MODES = /*#__PURE__*/Object.freeze({\n __proto__: null,\n MATCH_NOTHING_RE: MATCH_NOTHING_RE,\n IDENT_RE: IDENT_RE,\n UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,\n NUMBER_RE: NUMBER_RE,\n C_NUMBER_RE: C_NUMBER_RE,\n BINARY_NUMBER_RE: BINARY_NUMBER_RE,\n RE_STARTERS_RE: RE_STARTERS_RE,\n SHEBANG: SHEBANG,\n BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,\n APOS_STRING_MODE: APOS_STRING_MODE,\n QUOTE_STRING_MODE: QUOTE_STRING_MODE,\n PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,\n COMMENT: COMMENT,\n C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,\n C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,\n HASH_COMMENT_MODE: HASH_COMMENT_MODE,\n NUMBER_MODE: NUMBER_MODE,\n C_NUMBER_MODE: C_NUMBER_MODE,\n BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,\n CSS_NUMBER_MODE: CSS_NUMBER_MODE,\n REGEXP_MODE: REGEXP_MODE,\n TITLE_MODE: TITLE_MODE,\n UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,\n METHOD_GUARD: METHOD_GUARD,\n END_SAME_AS_BEGIN: END_SAME_AS_BEGIN\n});\n\n// Grammar extensions / plugins\n// See: https://github.com/highlightjs/highlight.js/issues/2833\n\n// Grammar extensions allow \"syntactic sugar\" to be added to the grammar modes\n// without requiring any underlying changes to the compiler internals.\n\n// `compileMatch` being the perfect small example of now allowing a grammar\n// author to write `match` when they desire to match a single expression rather\n// than being forced to use `begin`. The extension then just moves `match` into\n// `begin` when it runs. Ie, no features have been added, but we've just made\n// the experience of writing (and reading grammars) a little bit nicer.\n\n// ------\n\n// TODO: We need negative look-behind support to do this properly\n/**\n * Skip a match if it has a preceding dot\n *\n * This is used for `beginKeywords` to prevent matching expressions such as\n * `bob.keyword.do()`. The mode compiler automatically wires this up as a\n * special _internal_ 'on:begin' callback for modes with `beginKeywords`\n * @param {RegExpMatchArray} match\n * @param {CallbackResponse} response\n */\nfunction skipIfhasPrecedingDot(match, response) {\n const before = match.input[match.index - 1];\n if (before === \".\") {\n response.ignoreMatch();\n }\n}\n\n\n/**\n * `beginKeywords` syntactic sugar\n * @type {CompilerExt}\n */\nfunction beginKeywords(mode, parent) {\n if (!parent) return;\n if (!mode.beginKeywords) return;\n\n // for languages with keywords that include non-word characters checking for\n // a word boundary is not sufficient, so instead we check for a word boundary\n // or whitespace - this does no harm in any case since our keyword engine\n // doesn't allow spaces in keywords anyways and we still check for the boundary\n // first\n mode.begin = '\\\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\\\.)(?=\\\\b|\\\\s)';\n mode.__beforeBegin = skipIfhasPrecedingDot;\n mode.keywords = mode.keywords || mode.beginKeywords;\n delete mode.beginKeywords;\n\n // prevents double relevance, the keywords themselves provide\n // relevance, the mode doesn't need to double it\n // eslint-disable-next-line no-undefined\n if (mode.relevance === undefined) mode.relevance = 0;\n}\n\n/**\n * Allow `illegal` to contain an array of illegal values\n * @type {CompilerExt}\n */\nfunction compileIllegal(mode, _parent) {\n if (!Array.isArray(mode.illegal)) return;\n\n mode.illegal = either(...mode.illegal);\n}\n\n/**\n * `match` to match a single expression for readability\n * @type {CompilerExt}\n */\nfunction compileMatch(mode, _parent) {\n if (!mode.match) return;\n if (mode.begin || mode.end) throw new Error(\"begin & end are not supported with match\");\n\n mode.begin = mode.match;\n delete mode.match;\n}\n\n/**\n * provides the default 1 relevance to all modes\n * @type {CompilerExt}\n */\nfunction compileRelevance(mode, _parent) {\n // eslint-disable-next-line no-undefined\n if (mode.relevance === undefined) mode.relevance = 1;\n}\n\n// keywords that should have no default relevance value\nconst COMMON_KEYWORDS = [\n 'of',\n 'and',\n 'for',\n 'in',\n 'not',\n 'or',\n 'if',\n 'then',\n 'parent', // common variable name\n 'list', // common variable name\n 'value' // common variable name\n];\n\nconst DEFAULT_KEYWORD_CLASSNAME = \"keyword\";\n\n/**\n * Given raw keywords from a language definition, compile them.\n *\n * @param {string | Record | Array} rawKeywords\n * @param {boolean} caseInsensitive\n */\nfunction compileKeywords(rawKeywords, caseInsensitive, className = DEFAULT_KEYWORD_CLASSNAME) {\n /** @type KeywordDict */\n const compiledKeywords = {};\n\n // input can be a string of keywords, an array of keywords, or a object with\n // named keys representing className (which can then point to a string or array)\n if (typeof rawKeywords === 'string') {\n compileList(className, rawKeywords.split(\" \"));\n } else if (Array.isArray(rawKeywords)) {\n compileList(className, rawKeywords);\n } else {\n Object.keys(rawKeywords).forEach(function(className) {\n // collapse all our objects back into the parent object\n Object.assign(\n compiledKeywords,\n compileKeywords(rawKeywords[className], caseInsensitive, className)\n );\n });\n }\n return compiledKeywords;\n\n // ---\n\n /**\n * Compiles an individual list of keywords\n *\n * Ex: \"for if when while|5\"\n *\n * @param {string} className\n * @param {Array} keywordList\n */\n function compileList(className, keywordList) {\n if (caseInsensitive) {\n keywordList = keywordList.map(x => x.toLowerCase());\n }\n keywordList.forEach(function(keyword) {\n const pair = keyword.split('|');\n compiledKeywords[pair[0]] = [className, scoreForKeyword(pair[0], pair[1])];\n });\n }\n}\n\n/**\n * Returns the proper score for a given keyword\n *\n * Also takes into account comment keywords, which will be scored 0 UNLESS\n * another score has been manually assigned.\n * @param {string} keyword\n * @param {string} [providedScore]\n */\nfunction scoreForKeyword(keyword, providedScore) {\n // manual scores always win over common keywords\n // so you can force a score of 1 if you really insist\n if (providedScore) {\n return Number(providedScore);\n }\n\n return commonKeyword(keyword) ? 0 : 1;\n}\n\n/**\n * Determines if a given keyword is common or not\n *\n * @param {string} keyword */\nfunction commonKeyword(keyword) {\n return COMMON_KEYWORDS.includes(keyword.toLowerCase());\n}\n\n// compilation\n\n/**\n * Compiles a language definition result\n *\n * Given the raw result of a language definition (Language), compiles this so\n * that it is ready for highlighting code.\n * @param {Language} language\n * @param {{plugins: HLJSPlugin[]}} opts\n * @returns {CompiledLanguage}\n */\nfunction compileLanguage(language, { plugins }) {\n /**\n * Builds a regex with the case sensativility of the current language\n *\n * @param {RegExp | string} value\n * @param {boolean} [global]\n */\n function langRe(value, global) {\n return new RegExp(\n source(value),\n 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')\n );\n }\n\n /**\n Stores multiple regular expressions and allows you to quickly search for\n them all in a string simultaneously - returning the first match. It does\n this by creating a huge (a|b|c) regex - each individual item wrapped with ()\n and joined by `|` - using match groups to track position. When a match is\n found checking which position in the array has content allows us to figure\n out which of the original regexes / match groups triggered the match.\n\n The match object itself (the result of `Regex.exec`) is returned but also\n enhanced by merging in any meta-data that was registered with the regex.\n This is how we keep track of which mode matched, and what type of rule\n (`illegal`, `begin`, end, etc).\n */\n class MultiRegex {\n constructor() {\n this.matchIndexes = {};\n // @ts-ignore\n this.regexes = [];\n this.matchAt = 1;\n this.position = 0;\n }\n\n // @ts-ignore\n addRule(re, opts) {\n opts.position = this.position++;\n // @ts-ignore\n this.matchIndexes[this.matchAt] = opts;\n this.regexes.push([opts, re]);\n this.matchAt += countMatchGroups(re) + 1;\n }\n\n compile() {\n if (this.regexes.length === 0) {\n // avoids the need to check length every time exec is called\n // @ts-ignore\n this.exec = () => null;\n }\n const terminators = this.regexes.map(el => el[1]);\n this.matcherRe = langRe(join(terminators), true);\n this.lastIndex = 0;\n }\n\n /** @param {string} s */\n exec(s) {\n this.matcherRe.lastIndex = this.lastIndex;\n const match = this.matcherRe.exec(s);\n if (!match) { return null; }\n\n // eslint-disable-next-line no-undefined\n const i = match.findIndex((el, i) => i > 0 && el !== undefined);\n // @ts-ignore\n const matchData = this.matchIndexes[i];\n // trim off any earlier non-relevant match groups (ie, the other regex\n // match groups that make up the multi-matcher)\n match.splice(0, i);\n\n return Object.assign(match, matchData);\n }\n }\n\n /*\n Created to solve the key deficiently with MultiRegex - there is no way to\n test for multiple matches at a single location. Why would we need to do\n that? In the future a more dynamic engine will allow certain matches to be\n ignored. An example: if we matched say the 3rd regex in a large group but\n decided to ignore it - we'd need to started testing again at the 4th\n regex... but MultiRegex itself gives us no real way to do that.\n\n So what this class creates MultiRegexs on the fly for whatever search\n position they are needed.\n\n NOTE: These additional MultiRegex objects are created dynamically. For most\n grammars most of the time we will never actually need anything more than the\n first MultiRegex - so this shouldn't have too much overhead.\n\n Say this is our search group, and we match regex3, but wish to ignore it.\n\n regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0\n\n What we need is a new MultiRegex that only includes the remaining\n possibilities:\n\n regex4 | regex5 ' ie, startAt = 3\n\n This class wraps all that complexity up in a simple API... `startAt` decides\n where in the array of expressions to start doing the matching. It\n auto-increments, so if a match is found at position 2, then startAt will be\n set to 3. If the end is reached startAt will return to 0.\n\n MOST of the time the parser will be setting startAt manually to 0.\n */\n class ResumableMultiRegex {\n constructor() {\n // @ts-ignore\n this.rules = [];\n // @ts-ignore\n this.multiRegexes = [];\n this.count = 0;\n\n this.lastIndex = 0;\n this.regexIndex = 0;\n }\n\n // @ts-ignore\n getMatcher(index) {\n if (this.multiRegexes[index]) return this.multiRegexes[index];\n\n const matcher = new MultiRegex();\n this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));\n matcher.compile();\n this.multiRegexes[index] = matcher;\n return matcher;\n }\n\n resumingScanAtSamePosition() {\n return this.regexIndex !== 0;\n }\n\n considerAll() {\n this.regexIndex = 0;\n }\n\n // @ts-ignore\n addRule(re, opts) {\n this.rules.push([re, opts]);\n if (opts.type === \"begin\") this.count++;\n }\n\n /** @param {string} s */\n exec(s) {\n const m = this.getMatcher(this.regexIndex);\n m.lastIndex = this.lastIndex;\n let result = m.exec(s);\n\n // The following is because we have no easy way to say \"resume scanning at the\n // existing position but also skip the current rule ONLY\". What happens is\n // all prior rules are also skipped which can result in matching the wrong\n // thing. Example of matching \"booger\":\n\n // our matcher is [string, \"booger\", number]\n //\n // ....booger....\n\n // if \"booger\" is ignored then we'd really need a regex to scan from the\n // SAME position for only: [string, number] but ignoring \"booger\" (if it\n // was the first match), a simple resume would scan ahead who knows how\n // far looking only for \"number\", ignoring potential string matches (or\n // future \"booger\" matches that might be valid.)\n\n // So what we do: We execute two matchers, one resuming at the same\n // position, but the second full matcher starting at the position after:\n\n // /--- resume first regex match here (for [number])\n // |/---- full match here for [string, \"booger\", number]\n // vv\n // ....booger....\n\n // Which ever results in a match first is then used. So this 3-4 step\n // process essentially allows us to say \"match at this position, excluding\n // a prior rule that was ignored\".\n //\n // 1. Match \"booger\" first, ignore. Also proves that [string] does non match.\n // 2. Resume matching for [number]\n // 3. Match at index + 1 for [string, \"booger\", number]\n // 4. If #2 and #3 result in matches, which came first?\n if (this.resumingScanAtSamePosition()) {\n if (result && result.index === this.lastIndex) ; else { // use the second matcher result\n const m2 = this.getMatcher(0);\n m2.lastIndex = this.lastIndex + 1;\n result = m2.exec(s);\n }\n }\n\n if (result) {\n this.regexIndex += result.position + 1;\n if (this.regexIndex === this.count) {\n // wrap-around to considering all matches again\n this.considerAll();\n }\n }\n\n return result;\n }\n }\n\n /**\n * Given a mode, builds a huge ResumableMultiRegex that can be used to walk\n * the content and find matches.\n *\n * @param {CompiledMode} mode\n * @returns {ResumableMultiRegex}\n */\n function buildModeRegex(mode) {\n const mm = new ResumableMultiRegex();\n\n mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: \"begin\" }));\n\n if (mode.terminatorEnd) {\n mm.addRule(mode.terminatorEnd, { type: \"end\" });\n }\n if (mode.illegal) {\n mm.addRule(mode.illegal, { type: \"illegal\" });\n }\n\n return mm;\n }\n\n /** skip vs abort vs ignore\n *\n * @skip - The mode is still entered and exited normally (and contains rules apply),\n * but all content is held and added to the parent buffer rather than being\n * output when the mode ends. Mostly used with `sublanguage` to build up\n * a single large buffer than can be parsed by sublanguage.\n *\n * - The mode begin ands ends normally.\n * - Content matched is added to the parent mode buffer.\n * - The parser cursor is moved forward normally.\n *\n * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it\n * never matched) but DOES NOT continue to match subsequent `contains`\n * modes. Abort is bad/suboptimal because it can result in modes\n * farther down not getting applied because an earlier rule eats the\n * content but then aborts.\n *\n * - The mode does not begin.\n * - Content matched by `begin` is added to the mode buffer.\n * - The parser cursor is moved forward accordingly.\n *\n * @ignore - Ignores the mode (as if it never matched) and continues to match any\n * subsequent `contains` modes. Ignore isn't technically possible with\n * the current parser implementation.\n *\n * - The mode does not begin.\n * - Content matched by `begin` is ignored.\n * - The parser cursor is not moved forward.\n */\n\n /**\n * Compiles an individual mode\n *\n * This can raise an error if the mode contains certain detectable known logic\n * issues.\n * @param {Mode} mode\n * @param {CompiledMode | null} [parent]\n * @returns {CompiledMode | never}\n */\n function compileMode(mode, parent) {\n const cmode = /** @type CompiledMode */ (mode);\n if (mode.isCompiled) return cmode;\n\n [\n // do this early so compiler extensions generally don't have to worry about\n // the distinction between match/begin\n compileMatch\n ].forEach(ext => ext(mode, parent));\n\n language.compilerExtensions.forEach(ext => ext(mode, parent));\n\n // __beforeBegin is considered private API, internal use only\n mode.__beforeBegin = null;\n\n [\n beginKeywords,\n // do this later so compiler extensions that come earlier have access to the\n // raw array if they wanted to perhaps manipulate it, etc.\n compileIllegal,\n // default to 1 relevance if not specified\n compileRelevance\n ].forEach(ext => ext(mode, parent));\n\n mode.isCompiled = true;\n\n let keywordPattern = null;\n if (typeof mode.keywords === \"object\") {\n keywordPattern = mode.keywords.$pattern;\n delete mode.keywords.$pattern;\n }\n\n if (mode.keywords) {\n mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);\n }\n\n // both are not allowed\n if (mode.lexemes && keywordPattern) {\n throw new Error(\"ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) \");\n }\n\n // `mode.lexemes` was the old standard before we added and now recommend\n // using `keywords.$pattern` to pass the keyword pattern\n keywordPattern = keywordPattern || mode.lexemes || /\\w+/;\n cmode.keywordPatternRe = langRe(keywordPattern, true);\n\n if (parent) {\n if (!mode.begin) mode.begin = /\\B|\\b/;\n cmode.beginRe = langRe(mode.begin);\n if (mode.endSameAsBegin) mode.end = mode.begin;\n if (!mode.end && !mode.endsWithParent) mode.end = /\\B|\\b/;\n if (mode.end) cmode.endRe = langRe(mode.end);\n cmode.terminatorEnd = source(mode.end) || '';\n if (mode.endsWithParent && parent.terminatorEnd) {\n cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;\n }\n }\n if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));\n if (!mode.contains) mode.contains = [];\n\n mode.contains = [].concat(...mode.contains.map(function(c) {\n return expandOrCloneMode(c === 'self' ? mode : c);\n }));\n mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });\n\n if (mode.starts) {\n compileMode(mode.starts, parent);\n }\n\n cmode.matcher = buildModeRegex(cmode);\n return cmode;\n }\n\n if (!language.compilerExtensions) language.compilerExtensions = [];\n\n // self is not valid at the top-level\n if (language.contains && language.contains.includes('self')) {\n throw new Error(\"ERR: contains `self` is not supported at the top-level of a language. See documentation.\");\n }\n\n // we need a null object, which inherit will guarantee\n language.classNameAliases = inherit(language.classNameAliases || {});\n\n return compileMode(/** @type Mode */ (language));\n}\n\n/**\n * Determines if a mode has a dependency on it's parent or not\n *\n * If a mode does have a parent dependency then often we need to clone it if\n * it's used in multiple places so that each copy points to the correct parent,\n * where-as modes without a parent can often safely be re-used at the bottom of\n * a mode chain.\n *\n * @param {Mode | null} mode\n * @returns {boolean} - is there a dependency on the parent?\n * */\nfunction dependencyOnParent(mode) {\n if (!mode) return false;\n\n return mode.endsWithParent || dependencyOnParent(mode.starts);\n}\n\n/**\n * Expands a mode or clones it if necessary\n *\n * This is necessary for modes with parental dependenceis (see notes on\n * `dependencyOnParent`) and for nodes that have `variants` - which must then be\n * exploded into their own individual modes at compile time.\n *\n * @param {Mode} mode\n * @returns {Mode | Mode[]}\n * */\nfunction expandOrCloneMode(mode) {\n if (mode.variants && !mode.cachedVariants) {\n mode.cachedVariants = mode.variants.map(function(variant) {\n return inherit(mode, { variants: null }, variant);\n });\n }\n\n // EXPAND\n // if we have variants then essentially \"replace\" the mode with the variants\n // this happens in compileMode, where this function is called from\n if (mode.cachedVariants) {\n return mode.cachedVariants;\n }\n\n // CLONE\n // if we have dependencies on parents then we need a unique\n // instance of ourselves, so we can be reused with many\n // different parents without issue\n if (dependencyOnParent(mode)) {\n return inherit(mode, { starts: mode.starts ? inherit(mode.starts) : null });\n }\n\n if (Object.isFrozen(mode)) {\n return inherit(mode);\n }\n\n // no special dependency issues, just return ourselves\n return mode;\n}\n\nvar version = \"10.7.3\";\n\n// @ts-nocheck\n\nfunction hasValueOrEmptyAttribute(value) {\n return Boolean(value || value === \"\");\n}\n\nfunction BuildVuePlugin(hljs) {\n const Component = {\n props: [\"language\", \"code\", \"autodetect\"],\n data: function() {\n return {\n detectedLanguage: \"\",\n unknownLanguage: false\n };\n },\n computed: {\n className() {\n if (this.unknownLanguage) return \"\";\n\n return \"hljs \" + this.detectedLanguage;\n },\n highlighted() {\n // no idea what language to use, return raw code\n if (!this.autoDetect && !hljs.getLanguage(this.language)) {\n console.warn(`The language \"${this.language}\" you specified could not be found.`);\n this.unknownLanguage = true;\n return escapeHTML(this.code);\n }\n\n let result = {};\n if (this.autoDetect) {\n result = hljs.highlightAuto(this.code);\n this.detectedLanguage = result.language;\n } else {\n result = hljs.highlight(this.language, this.code, this.ignoreIllegals);\n this.detectedLanguage = this.language;\n }\n return result.value;\n },\n autoDetect() {\n return !this.language || hasValueOrEmptyAttribute(this.autodetect);\n },\n ignoreIllegals() {\n return true;\n }\n },\n // this avoids needing to use a whole Vue compilation pipeline just\n // to build Highlight.js\n render(createElement) {\n return createElement(\"pre\", {}, [\n createElement(\"code\", {\n class: this.className,\n domProps: { innerHTML: this.highlighted }\n })\n ]);\n }\n // template: `
`\n };\n\n const VuePlugin = {\n install(Vue) {\n Vue.component('highlightjs', Component);\n }\n };\n\n return { Component, VuePlugin };\n}\n\n/* plugin itself */\n\n/** @type {HLJSPlugin} */\nconst mergeHTMLPlugin = {\n \"after:highlightElement\": ({ el, result, text }) => {\n const originalStream = nodeStream(el);\n if (!originalStream.length) return;\n\n const resultNode = document.createElement('div');\n resultNode.innerHTML = result.value;\n result.value = mergeStreams(originalStream, nodeStream(resultNode), text);\n }\n};\n\n/* Stream merging support functions */\n\n/**\n * @typedef Event\n * @property {'start'|'stop'} event\n * @property {number} offset\n * @property {Node} node\n */\n\n/**\n * @param {Node} node\n */\nfunction tag(node) {\n return node.nodeName.toLowerCase();\n}\n\n/**\n * @param {Node} node\n */\nfunction nodeStream(node) {\n /** @type Event[] */\n const result = [];\n (function _nodeStream(node, offset) {\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === 3) {\n offset += child.nodeValue.length;\n } else if (child.nodeType === 1) {\n result.push({\n event: 'start',\n offset: offset,\n node: child\n });\n offset = _nodeStream(child, offset);\n // Prevent void elements from having an end tag that would actually\n // double them in the output. There are more void elements in HTML\n // but we list only those realistically expected in code display.\n if (!tag(child).match(/br|hr|img|input/)) {\n result.push({\n event: 'stop',\n offset: offset,\n node: child\n });\n }\n }\n }\n return offset;\n })(node, 0);\n return result;\n}\n\n/**\n * @param {any} original - the original stream\n * @param {any} highlighted - stream of the highlighted source\n * @param {string} value - the original source itself\n */\nfunction mergeStreams(original, highlighted, value) {\n let processed = 0;\n let result = '';\n const nodeStack = [];\n\n function selectStream() {\n if (!original.length || !highlighted.length) {\n return original.length ? original : highlighted;\n }\n if (original[0].offset !== highlighted[0].offset) {\n return (original[0].offset < highlighted[0].offset) ? original : highlighted;\n }\n\n /*\n To avoid starting the stream just before it should stop the order is\n ensured that original always starts first and closes last:\n\n if (event1 == 'start' && event2 == 'start')\n return original;\n if (event1 == 'start' && event2 == 'stop')\n return highlighted;\n if (event1 == 'stop' && event2 == 'start')\n return original;\n if (event1 == 'stop' && event2 == 'stop')\n return highlighted;\n\n ... which is collapsed to:\n */\n return highlighted[0].event === 'start' ? original : highlighted;\n }\n\n /**\n * @param {Node} node\n */\n function open(node) {\n /** @param {Attr} attr */\n function attributeString(attr) {\n return ' ' + attr.nodeName + '=\"' + escapeHTML(attr.value) + '\"';\n }\n // @ts-ignore\n result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('') + '>';\n }\n\n /**\n * @param {Node} node\n */\n function close(node) {\n result += '';\n }\n\n /**\n * @param {Event} event\n */\n function render(event) {\n (event.event === 'start' ? open : close)(event.node);\n }\n\n while (original.length || highlighted.length) {\n let stream = selectStream();\n result += escapeHTML(value.substring(processed, stream[0].offset));\n processed = stream[0].offset;\n if (stream === original) {\n /*\n On any opening or closing tag of the original markup we first close\n the entire highlighted node stack, then render the original tag along\n with all the following original tags at the same offset and then\n reopen all the tags on the highlighted stack.\n */\n nodeStack.reverse().forEach(close);\n do {\n render(stream.splice(0, 1)[0]);\n stream = selectStream();\n } while (stream === original && stream.length && stream[0].offset === processed);\n nodeStack.reverse().forEach(open);\n } else {\n if (stream[0].event === 'start') {\n nodeStack.push(stream[0].node);\n } else {\n nodeStack.pop();\n }\n render(stream.splice(0, 1)[0]);\n }\n }\n return result + escapeHTML(value.substr(processed));\n}\n\n/*\n\nFor the reasoning behind this please see:\nhttps://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419\n\n*/\n\n/**\n * @type {Record}\n */\nconst seenDeprecations = {};\n\n/**\n * @param {string} message\n */\nconst error = (message) => {\n console.error(message);\n};\n\n/**\n * @param {string} message\n * @param {any} args\n */\nconst warn = (message, ...args) => {\n console.log(`WARN: ${message}`, ...args);\n};\n\n/**\n * @param {string} version\n * @param {string} message\n */\nconst deprecated = (version, message) => {\n if (seenDeprecations[`${version}/${message}`]) return;\n\n console.log(`Deprecated as of ${version}. ${message}`);\n seenDeprecations[`${version}/${message}`] = true;\n};\n\n/*\nSyntax highlighting with language autodetection.\nhttps://highlightjs.org/\n*/\n\nconst escape$1 = escapeHTML;\nconst inherit$1 = inherit;\nconst NO_MATCH = Symbol(\"nomatch\");\n\n/**\n * @param {any} hljs - object that is extended (legacy)\n * @returns {HLJSApi}\n */\nconst HLJS = function(hljs) {\n // Global internal variables used within the highlight.js library.\n /** @type {Record} */\n const languages = Object.create(null);\n /** @type {Record} */\n const aliases = Object.create(null);\n /** @type {HLJSPlugin[]} */\n const plugins = [];\n\n // safe/production mode - swallows more errors, tries to keep running\n // even if a single syntax or parse hits a fatal error\n let SAFE_MODE = true;\n const fixMarkupRe = /(^(<[^>]+>|\\t|)+|\\n)/gm;\n const LANGUAGE_NOT_FOUND = \"Could not find the language '{}', did you forget to load/include a language module?\";\n /** @type {Language} */\n const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };\n\n // Global options used when within external APIs. This is modified when\n // calling the `hljs.configure` function.\n /** @type HLJSOptions */\n let options = {\n noHighlightRe: /^(no-?highlight)$/i,\n languageDetectRe: /\\blang(?:uage)?-([\\w-]+)\\b/i,\n classPrefix: 'hljs-',\n tabReplace: null,\n useBR: false,\n languages: null,\n // beta configuration options, subject to change, welcome to discuss\n // https://github.com/highlightjs/highlight.js/issues/1086\n __emitter: TokenTreeEmitter\n };\n\n /* Utility functions */\n\n /**\n * Tests a language name to see if highlighting should be skipped\n * @param {string} languageName\n */\n function shouldNotHighlight(languageName) {\n return options.noHighlightRe.test(languageName);\n }\n\n /**\n * @param {HighlightedHTMLElement} block - the HTML element to determine language for\n */\n function blockLanguage(block) {\n let classes = block.className + ' ';\n\n classes += block.parentNode ? block.parentNode.className : '';\n\n // language-* takes precedence over non-prefixed class names.\n const match = options.languageDetectRe.exec(classes);\n if (match) {\n const language = getLanguage(match[1]);\n if (!language) {\n warn(LANGUAGE_NOT_FOUND.replace(\"{}\", match[1]));\n warn(\"Falling back to no-highlight mode for this block.\", block);\n }\n return language ? match[1] : 'no-highlight';\n }\n\n return classes\n .split(/\\s+/)\n .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));\n }\n\n /**\n * Core highlighting function.\n *\n * OLD API\n * highlight(lang, code, ignoreIllegals, continuation)\n *\n * NEW API\n * highlight(code, {lang, ignoreIllegals})\n *\n * @param {string} codeOrlanguageName - the language to use for highlighting\n * @param {string | HighlightOptions} optionsOrCode - the code to highlight\n * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n * @param {CompiledMode} [continuation] - current continuation mode, if any\n *\n * @returns {HighlightResult} Result - an object that represents the result\n * @property {string} language - the language name\n * @property {number} relevance - the relevance score\n * @property {string} value - the highlighted HTML code\n * @property {string} code - the original raw code\n * @property {CompiledMode} top - top of the current mode stack\n * @property {boolean} illegal - indicates whether any illegal matches were found\n */\n function highlight(codeOrlanguageName, optionsOrCode, ignoreIllegals, continuation) {\n let code = \"\";\n let languageName = \"\";\n if (typeof optionsOrCode === \"object\") {\n code = codeOrlanguageName;\n ignoreIllegals = optionsOrCode.ignoreIllegals;\n languageName = optionsOrCode.language;\n // continuation not supported at all via the new API\n // eslint-disable-next-line no-undefined\n continuation = undefined;\n } else {\n // old API\n deprecated(\"10.7.0\", \"highlight(lang, code, ...args) has been deprecated.\");\n deprecated(\"10.7.0\", \"Please use highlight(code, options) instead.\\nhttps://github.com/highlightjs/highlight.js/issues/2277\");\n languageName = codeOrlanguageName;\n code = optionsOrCode;\n }\n\n /** @type {BeforeHighlightContext} */\n const context = {\n code,\n language: languageName\n };\n // the plugin can change the desired language or the code to be highlighted\n // just be changing the object it was passed\n fire(\"before:highlight\", context);\n\n // a before plugin can usurp the result completely by providing it's own\n // in which case we don't even need to call highlight\n const result = context.result\n ? context.result\n : _highlight(context.language, context.code, ignoreIllegals, continuation);\n\n result.code = context.code;\n // the plugin can change anything in result to suite it\n fire(\"after:highlight\", result);\n\n return result;\n }\n\n /**\n * private highlight that's used internally and does not fire callbacks\n *\n * @param {string} languageName - the language to use for highlighting\n * @param {string} codeToHighlight - the code to highlight\n * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n * @param {CompiledMode?} [continuation] - current continuation mode, if any\n * @returns {HighlightResult} - result of the highlight operation\n */\n function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {\n /**\n * Return keyword data if a match is a keyword\n * @param {CompiledMode} mode - current mode\n * @param {RegExpMatchArray} match - regexp match data\n * @returns {KeywordData | false}\n */\n function keywordData(mode, match) {\n const matchText = language.case_insensitive ? match[0].toLowerCase() : match[0];\n return Object.prototype.hasOwnProperty.call(mode.keywords, matchText) && mode.keywords[matchText];\n }\n\n function processKeywords() {\n if (!top.keywords) {\n emitter.addText(modeBuffer);\n return;\n }\n\n let lastIndex = 0;\n top.keywordPatternRe.lastIndex = 0;\n let match = top.keywordPatternRe.exec(modeBuffer);\n let buf = \"\";\n\n while (match) {\n buf += modeBuffer.substring(lastIndex, match.index);\n const data = keywordData(top, match);\n if (data) {\n const [kind, keywordRelevance] = data;\n emitter.addText(buf);\n buf = \"\";\n\n relevance += keywordRelevance;\n if (kind.startsWith(\"_\")) {\n // _ implied for relevance only, do not highlight\n // by applying a class name\n buf += match[0];\n } else {\n const cssClass = language.classNameAliases[kind] || kind;\n emitter.addKeyword(match[0], cssClass);\n }\n } else {\n buf += match[0];\n }\n lastIndex = top.keywordPatternRe.lastIndex;\n match = top.keywordPatternRe.exec(modeBuffer);\n }\n buf += modeBuffer.substr(lastIndex);\n emitter.addText(buf);\n }\n\n function processSubLanguage() {\n if (modeBuffer === \"\") return;\n /** @type HighlightResult */\n let result = null;\n\n if (typeof top.subLanguage === 'string') {\n if (!languages[top.subLanguage]) {\n emitter.addText(modeBuffer);\n return;\n }\n result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);\n continuations[top.subLanguage] = /** @type {CompiledMode} */ (result.top);\n } else {\n result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);\n }\n\n // Counting embedded language score towards the host language may be disabled\n // with zeroing the containing mode relevance. Use case in point is Markdown that\n // allows XML everywhere and makes every XML snippet to have a much larger Markdown\n // score.\n if (top.relevance > 0) {\n relevance += result.relevance;\n }\n emitter.addSublanguage(result.emitter, result.language);\n }\n\n function processBuffer() {\n if (top.subLanguage != null) {\n processSubLanguage();\n } else {\n processKeywords();\n }\n modeBuffer = '';\n }\n\n /**\n * @param {Mode} mode - new mode to start\n */\n function startNewMode(mode) {\n if (mode.className) {\n emitter.openNode(language.classNameAliases[mode.className] || mode.className);\n }\n top = Object.create(mode, { parent: { value: top } });\n return top;\n }\n\n /**\n * @param {CompiledMode } mode - the mode to potentially end\n * @param {RegExpMatchArray} match - the latest match\n * @param {string} matchPlusRemainder - match plus remainder of content\n * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode\n */\n function endOfMode(mode, match, matchPlusRemainder) {\n let matched = startsWith(mode.endRe, matchPlusRemainder);\n\n if (matched) {\n if (mode[\"on:end\"]) {\n const resp = new Response(mode);\n mode[\"on:end\"](match, resp);\n if (resp.isMatchIgnored) matched = false;\n }\n\n if (matched) {\n while (mode.endsParent && mode.parent) {\n mode = mode.parent;\n }\n return mode;\n }\n }\n // even if on:end fires an `ignore` it's still possible\n // that we might trigger the end node because of a parent mode\n if (mode.endsWithParent) {\n return endOfMode(mode.parent, match, matchPlusRemainder);\n }\n }\n\n /**\n * Handle matching but then ignoring a sequence of text\n *\n * @param {string} lexeme - string containing full match text\n */\n function doIgnore(lexeme) {\n if (top.matcher.regexIndex === 0) {\n // no more regexs to potentially match here, so we move the cursor forward one\n // space\n modeBuffer += lexeme[0];\n return 1;\n } else {\n // no need to move the cursor, we still have additional regexes to try and\n // match at this very spot\n resumeScanAtSamePosition = true;\n return 0;\n }\n }\n\n /**\n * Handle the start of a new potential mode match\n *\n * @param {EnhancedMatch} match - the current match\n * @returns {number} how far to advance the parse cursor\n */\n function doBeginMatch(match) {\n const lexeme = match[0];\n const newMode = match.rule;\n\n const resp = new Response(newMode);\n // first internal before callbacks, then the public ones\n const beforeCallbacks = [newMode.__beforeBegin, newMode[\"on:begin\"]];\n for (const cb of beforeCallbacks) {\n if (!cb) continue;\n cb(match, resp);\n if (resp.isMatchIgnored) return doIgnore(lexeme);\n }\n\n if (newMode && newMode.endSameAsBegin) {\n newMode.endRe = escape(lexeme);\n }\n\n if (newMode.skip) {\n modeBuffer += lexeme;\n } else {\n if (newMode.excludeBegin) {\n modeBuffer += lexeme;\n }\n processBuffer();\n if (!newMode.returnBegin && !newMode.excludeBegin) {\n modeBuffer = lexeme;\n }\n }\n startNewMode(newMode);\n // if (mode[\"after:begin\"]) {\n // let resp = new Response(mode);\n // mode[\"after:begin\"](match, resp);\n // }\n return newMode.returnBegin ? 0 : lexeme.length;\n }\n\n /**\n * Handle the potential end of mode\n *\n * @param {RegExpMatchArray} match - the current match\n */\n function doEndMatch(match) {\n const lexeme = match[0];\n const matchPlusRemainder = codeToHighlight.substr(match.index);\n\n const endMode = endOfMode(top, match, matchPlusRemainder);\n if (!endMode) { return NO_MATCH; }\n\n const origin = top;\n if (origin.skip) {\n modeBuffer += lexeme;\n } else {\n if (!(origin.returnEnd || origin.excludeEnd)) {\n modeBuffer += lexeme;\n }\n processBuffer();\n if (origin.excludeEnd) {\n modeBuffer = lexeme;\n }\n }\n do {\n if (top.className) {\n emitter.closeNode();\n }\n if (!top.skip && !top.subLanguage) {\n relevance += top.relevance;\n }\n top = top.parent;\n } while (top !== endMode.parent);\n if (endMode.starts) {\n if (endMode.endSameAsBegin) {\n endMode.starts.endRe = endMode.endRe;\n }\n startNewMode(endMode.starts);\n }\n return origin.returnEnd ? 0 : lexeme.length;\n }\n\n function processContinuations() {\n const list = [];\n for (let current = top; current !== language; current = current.parent) {\n if (current.className) {\n list.unshift(current.className);\n }\n }\n list.forEach(item => emitter.openNode(item));\n }\n\n /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */\n let lastMatch = {};\n\n /**\n * Process an individual match\n *\n * @param {string} textBeforeMatch - text preceeding the match (since the last match)\n * @param {EnhancedMatch} [match] - the match itself\n */\n function processLexeme(textBeforeMatch, match) {\n const lexeme = match && match[0];\n\n // add non-matched text to the current mode buffer\n modeBuffer += textBeforeMatch;\n\n if (lexeme == null) {\n processBuffer();\n return 0;\n }\n\n // we've found a 0 width match and we're stuck, so we need to advance\n // this happens when we have badly behaved rules that have optional matchers to the degree that\n // sometimes they can end up matching nothing at all\n // Ref: https://github.com/highlightjs/highlight.js/issues/2140\n if (lastMatch.type === \"begin\" && match.type === \"end\" && lastMatch.index === match.index && lexeme === \"\") {\n // spit the \"skipped\" character that our regex choked on back into the output sequence\n modeBuffer += codeToHighlight.slice(match.index, match.index + 1);\n if (!SAFE_MODE) {\n /** @type {AnnotatedError} */\n const err = new Error('0 width match regex');\n err.languageName = languageName;\n err.badRule = lastMatch.rule;\n throw err;\n }\n return 1;\n }\n lastMatch = match;\n\n if (match.type === \"begin\") {\n return doBeginMatch(match);\n } else if (match.type === \"illegal\" && !ignoreIllegals) {\n // illegal match, we do not continue processing\n /** @type {AnnotatedError} */\n const err = new Error('Illegal lexeme \"' + lexeme + '\" for mode \"' + (top.className || '') + '\"');\n err.mode = top;\n throw err;\n } else if (match.type === \"end\") {\n const processed = doEndMatch(match);\n if (processed !== NO_MATCH) {\n return processed;\n }\n }\n\n // edge case for when illegal matches $ (end of line) which is technically\n // a 0 width match but not a begin/end match so it's not caught by the\n // first handler (when ignoreIllegals is true)\n if (match.type === \"illegal\" && lexeme === \"\") {\n // advance so we aren't stuck in an infinite loop\n return 1;\n }\n\n // infinite loops are BAD, this is a last ditch catch all. if we have a\n // decent number of iterations yet our index (cursor position in our\n // parsing) still 3x behind our index then something is very wrong\n // so we bail\n if (iterations > 100000 && iterations > match.index * 3) {\n const err = new Error('potential infinite loop, way more iterations than matches');\n throw err;\n }\n\n /*\n Why might be find ourselves here? Only one occasion now. An end match that was\n triggered but could not be completed. When might this happen? When an `endSameasBegin`\n rule sets the end rule to a specific match. Since the overall mode termination rule that's\n being used to scan the text isn't recompiled that means that any match that LOOKS like\n the end (but is not, because it is not an exact match to the beginning) will\n end up here. A definite end match, but when `doEndMatch` tries to \"reapply\"\n the end rule and fails to match, we wind up here, and just silently ignore the end.\n\n This causes no real harm other than stopping a few times too many.\n */\n\n modeBuffer += lexeme;\n return lexeme.length;\n }\n\n const language = getLanguage(languageName);\n if (!language) {\n error(LANGUAGE_NOT_FOUND.replace(\"{}\", languageName));\n throw new Error('Unknown language: \"' + languageName + '\"');\n }\n\n const md = compileLanguage(language, { plugins });\n let result = '';\n /** @type {CompiledMode} */\n let top = continuation || md;\n /** @type Record */\n const continuations = {}; // keep continuations for sub-languages\n const emitter = new options.__emitter(options);\n processContinuations();\n let modeBuffer = '';\n let relevance = 0;\n let index = 0;\n let iterations = 0;\n let resumeScanAtSamePosition = false;\n\n try {\n top.matcher.considerAll();\n\n for (;;) {\n iterations++;\n if (resumeScanAtSamePosition) {\n // only regexes not matched previously will now be\n // considered for a potential match\n resumeScanAtSamePosition = false;\n } else {\n top.matcher.considerAll();\n }\n top.matcher.lastIndex = index;\n\n const match = top.matcher.exec(codeToHighlight);\n // console.log(\"match\", match[0], match.rule && match.rule.begin)\n\n if (!match) break;\n\n const beforeMatch = codeToHighlight.substring(index, match.index);\n const processedCount = processLexeme(beforeMatch, match);\n index = match.index + processedCount;\n }\n processLexeme(codeToHighlight.substr(index));\n emitter.closeAllNodes();\n emitter.finalize();\n result = emitter.toHTML();\n\n return {\n // avoid possible breakage with v10 clients expecting\n // this to always be an integer\n relevance: Math.floor(relevance),\n value: result,\n language: languageName,\n illegal: false,\n emitter: emitter,\n top: top\n };\n } catch (err) {\n if (err.message && err.message.includes('Illegal')) {\n return {\n illegal: true,\n illegalBy: {\n msg: err.message,\n context: codeToHighlight.slice(index - 100, index + 100),\n mode: err.mode\n },\n sofar: result,\n relevance: 0,\n value: escape$1(codeToHighlight),\n emitter: emitter\n };\n } else if (SAFE_MODE) {\n return {\n illegal: false,\n relevance: 0,\n value: escape$1(codeToHighlight),\n emitter: emitter,\n language: languageName,\n top: top,\n errorRaised: err\n };\n } else {\n throw err;\n }\n }\n }\n\n /**\n * returns a valid highlight result, without actually doing any actual work,\n * auto highlight starts with this and it's possible for small snippets that\n * auto-detection may not find a better match\n * @param {string} code\n * @returns {HighlightResult}\n */\n function justTextHighlightResult(code) {\n const result = {\n relevance: 0,\n emitter: new options.__emitter(options),\n value: escape$1(code),\n illegal: false,\n top: PLAINTEXT_LANGUAGE\n };\n result.emitter.addText(code);\n return result;\n }\n\n /**\n Highlighting with language detection. Accepts a string with the code to\n highlight. Returns an object with the following properties:\n\n - language (detected language)\n - relevance (int)\n - value (an HTML string with highlighting markup)\n - second_best (object with the same structure for second-best heuristically\n detected language, may be absent)\n\n @param {string} code\n @param {Array} [languageSubset]\n @returns {AutoHighlightResult}\n */\n function highlightAuto(code, languageSubset) {\n languageSubset = languageSubset || options.languages || Object.keys(languages);\n const plaintext = justTextHighlightResult(code);\n\n const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>\n _highlight(name, code, false)\n );\n results.unshift(plaintext); // plaintext is always an option\n\n const sorted = results.sort((a, b) => {\n // sort base on relevance\n if (a.relevance !== b.relevance) return b.relevance - a.relevance;\n\n // always award the tie to the base language\n // ie if C++ and Arduino are tied, it's more likely to be C++\n if (a.language && b.language) {\n if (getLanguage(a.language).supersetOf === b.language) {\n return 1;\n } else if (getLanguage(b.language).supersetOf === a.language) {\n return -1;\n }\n }\n\n // otherwise say they are equal, which has the effect of sorting on\n // relevance while preserving the original ordering - which is how ties\n // have historically been settled, ie the language that comes first always\n // wins in the case of a tie\n return 0;\n });\n\n const [best, secondBest] = sorted;\n\n /** @type {AutoHighlightResult} */\n const result = best;\n result.second_best = secondBest;\n\n return result;\n }\n\n /**\n Post-processing of the highlighted markup:\n\n - replace TABs with something more useful\n - replace real line-breaks with '
' for non-pre containers\n\n @param {string} html\n @returns {string}\n */\n function fixMarkup(html) {\n if (!(options.tabReplace || options.useBR)) {\n return html;\n }\n\n return html.replace(fixMarkupRe, match => {\n if (match === '\\n') {\n return options.useBR ? '
' : match;\n } else if (options.tabReplace) {\n return match.replace(/\\t/g, options.tabReplace);\n }\n return match;\n });\n }\n\n /**\n * Builds new class name for block given the language name\n *\n * @param {HTMLElement} element\n * @param {string} [currentLang]\n * @param {string} [resultLang]\n */\n function updateClassName(element, currentLang, resultLang) {\n const language = currentLang ? aliases[currentLang] : resultLang;\n\n element.classList.add(\"hljs\");\n if (language) element.classList.add(language);\n }\n\n /** @type {HLJSPlugin} */\n const brPlugin = {\n \"before:highlightElement\": ({ el }) => {\n if (options.useBR) {\n el.innerHTML = el.innerHTML.replace(/\\n/g, '').replace(//g, '\\n');\n }\n },\n \"after:highlightElement\": ({ result }) => {\n if (options.useBR) {\n result.value = result.value.replace(/\\n/g, \"
\");\n }\n }\n };\n\n const TAB_REPLACE_RE = /^(<[^>]+>|\\t)+/gm;\n /** @type {HLJSPlugin} */\n const tabReplacePlugin = {\n \"after:highlightElement\": ({ result }) => {\n if (options.tabReplace) {\n result.value = result.value.replace(TAB_REPLACE_RE, (m) =>\n m.replace(/\\t/g, options.tabReplace)\n );\n }\n }\n };\n\n /**\n * Applies highlighting to a DOM node containing code. Accepts a DOM node and\n * two optional parameters for fixMarkup.\n *\n * @param {HighlightedHTMLElement} element - the HTML element to highlight\n */\n function highlightElement(element) {\n /** @type HTMLElement */\n let node = null;\n const language = blockLanguage(element);\n\n if (shouldNotHighlight(language)) return;\n\n // support for v10 API\n fire(\"before:highlightElement\",\n { el: element, language: language });\n\n node = element;\n const text = node.textContent;\n const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);\n\n // support for v10 API\n fire(\"after:highlightElement\", { el: element, result, text });\n\n element.innerHTML = result.value;\n updateClassName(element, language, result.language);\n element.result = {\n language: result.language,\n // TODO: remove with version 11.0\n re: result.relevance,\n relavance: result.relevance\n };\n if (result.second_best) {\n element.second_best = {\n language: result.second_best.language,\n // TODO: remove with version 11.0\n re: result.second_best.relevance,\n relavance: result.second_best.relevance\n };\n }\n }\n\n /**\n * Updates highlight.js global options with the passed options\n *\n * @param {Partial} userOptions\n */\n function configure(userOptions) {\n if (userOptions.useBR) {\n deprecated(\"10.3.0\", \"'useBR' will be removed entirely in v11.0\");\n deprecated(\"10.3.0\", \"Please see https://github.com/highlightjs/highlight.js/issues/2559\");\n }\n options = inherit$1(options, userOptions);\n }\n\n /**\n * Highlights to all
 blocks on a page\n   *\n   * @type {Function & {called?: boolean}}\n   */\n  // TODO: remove v12, deprecated\n  const initHighlighting = () => {\n    if (initHighlighting.called) return;\n    initHighlighting.called = true;\n\n    deprecated(\"10.6.0\", \"initHighlighting() is deprecated.  Use highlightAll() instead.\");\n\n    const blocks = document.querySelectorAll('pre code');\n    blocks.forEach(highlightElement);\n  };\n\n  // Higlights all when DOMContentLoaded fires\n  // TODO: remove v12, deprecated\n  function initHighlightingOnLoad() {\n    deprecated(\"10.6.0\", \"initHighlightingOnLoad() is deprecated.  Use highlightAll() instead.\");\n    wantsHighlight = true;\n  }\n\n  let wantsHighlight = false;\n\n  /**\n   * auto-highlights all pre>code elements on the page\n   */\n  function highlightAll() {\n    // if we are called too early in the loading process\n    if (document.readyState === \"loading\") {\n      wantsHighlight = true;\n      return;\n    }\n\n    const blocks = document.querySelectorAll('pre code');\n    blocks.forEach(highlightElement);\n  }\n\n  function boot() {\n    // if a highlight was requested before DOM was loaded, do now\n    if (wantsHighlight) highlightAll();\n  }\n\n  // make sure we are in the browser environment\n  if (typeof window !== 'undefined' && window.addEventListener) {\n    window.addEventListener('DOMContentLoaded', boot, false);\n  }\n\n  /**\n   * Register a language grammar module\n   *\n   * @param {string} languageName\n   * @param {LanguageFn} languageDefinition\n   */\n  function registerLanguage(languageName, languageDefinition) {\n    let lang = null;\n    try {\n      lang = languageDefinition(hljs);\n    } catch (error$1) {\n      error(\"Language definition for '{}' could not be registered.\".replace(\"{}\", languageName));\n      // hard or soft error\n      if (!SAFE_MODE) { throw error$1; } else { error(error$1); }\n      // languages that have serious errors are replaced with essentially a\n      // \"plaintext\" stand-in so that the code blocks will still get normal\n      // css classes applied to them - and one bad language won't break the\n      // entire highlighter\n      lang = PLAINTEXT_LANGUAGE;\n    }\n    // give it a temporary name if it doesn't have one in the meta-data\n    if (!lang.name) lang.name = languageName;\n    languages[languageName] = lang;\n    lang.rawDefinition = languageDefinition.bind(null, hljs);\n\n    if (lang.aliases) {\n      registerAliases(lang.aliases, { languageName });\n    }\n  }\n\n  /**\n   * Remove a language grammar module\n   *\n   * @param {string} languageName\n   */\n  function unregisterLanguage(languageName) {\n    delete languages[languageName];\n    for (const alias of Object.keys(aliases)) {\n      if (aliases[alias] === languageName) {\n        delete aliases[alias];\n      }\n    }\n  }\n\n  /**\n   * @returns {string[]} List of language internal names\n   */\n  function listLanguages() {\n    return Object.keys(languages);\n  }\n\n  /**\n    intended usage: When one language truly requires another\n\n    Unlike `getLanguage`, this will throw when the requested language\n    is not available.\n\n    @param {string} name - name of the language to fetch/require\n    @returns {Language | never}\n  */\n  function requireLanguage(name) {\n    deprecated(\"10.4.0\", \"requireLanguage will be removed entirely in v11.\");\n    deprecated(\"10.4.0\", \"Please see https://github.com/highlightjs/highlight.js/pull/2844\");\n\n    const lang = getLanguage(name);\n    if (lang) { return lang; }\n\n    const err = new Error('The \\'{}\\' language is required, but not loaded.'.replace('{}', name));\n    throw err;\n  }\n\n  /**\n   * @param {string} name - name of the language to retrieve\n   * @returns {Language | undefined}\n   */\n  function getLanguage(name) {\n    name = (name || '').toLowerCase();\n    return languages[name] || languages[aliases[name]];\n  }\n\n  /**\n   *\n   * @param {string|string[]} aliasList - single alias or list of aliases\n   * @param {{languageName: string}} opts\n   */\n  function registerAliases(aliasList, { languageName }) {\n    if (typeof aliasList === 'string') {\n      aliasList = [aliasList];\n    }\n    aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });\n  }\n\n  /**\n   * Determines if a given language has auto-detection enabled\n   * @param {string} name - name of the language\n   */\n  function autoDetection(name) {\n    const lang = getLanguage(name);\n    return lang && !lang.disableAutodetect;\n  }\n\n  /**\n   * Upgrades the old highlightBlock plugins to the new\n   * highlightElement API\n   * @param {HLJSPlugin} plugin\n   */\n  function upgradePluginAPI(plugin) {\n    // TODO: remove with v12\n    if (plugin[\"before:highlightBlock\"] && !plugin[\"before:highlightElement\"]) {\n      plugin[\"before:highlightElement\"] = (data) => {\n        plugin[\"before:highlightBlock\"](\n          Object.assign({ block: data.el }, data)\n        );\n      };\n    }\n    if (plugin[\"after:highlightBlock\"] && !plugin[\"after:highlightElement\"]) {\n      plugin[\"after:highlightElement\"] = (data) => {\n        plugin[\"after:highlightBlock\"](\n          Object.assign({ block: data.el }, data)\n        );\n      };\n    }\n  }\n\n  /**\n   * @param {HLJSPlugin} plugin\n   */\n  function addPlugin(plugin) {\n    upgradePluginAPI(plugin);\n    plugins.push(plugin);\n  }\n\n  /**\n   *\n   * @param {PluginEvent} event\n   * @param {any} args\n   */\n  function fire(event, args) {\n    const cb = event;\n    plugins.forEach(function(plugin) {\n      if (plugin[cb]) {\n        plugin[cb](args);\n      }\n    });\n  }\n\n  /**\n  Note: fixMarkup is deprecated and will be removed entirely in v11\n\n  @param {string} arg\n  @returns {string}\n  */\n  function deprecateFixMarkup(arg) {\n    deprecated(\"10.2.0\", \"fixMarkup will be removed entirely in v11.0\");\n    deprecated(\"10.2.0\", \"Please see https://github.com/highlightjs/highlight.js/issues/2534\");\n\n    return fixMarkup(arg);\n  }\n\n  /**\n   *\n   * @param {HighlightedHTMLElement} el\n   */\n  function deprecateHighlightBlock(el) {\n    deprecated(\"10.7.0\", \"highlightBlock will be removed entirely in v12.0\");\n    deprecated(\"10.7.0\", \"Please use highlightElement now.\");\n\n    return highlightElement(el);\n  }\n\n  /* Interface definition */\n  Object.assign(hljs, {\n    highlight,\n    highlightAuto,\n    highlightAll,\n    fixMarkup: deprecateFixMarkup,\n    highlightElement,\n    // TODO: Remove with v12 API\n    highlightBlock: deprecateHighlightBlock,\n    configure,\n    initHighlighting,\n    initHighlightingOnLoad,\n    registerLanguage,\n    unregisterLanguage,\n    listLanguages,\n    getLanguage,\n    registerAliases,\n    requireLanguage,\n    autoDetection,\n    inherit: inherit$1,\n    addPlugin,\n    // plugins for frameworks\n    vuePlugin: BuildVuePlugin(hljs).VuePlugin\n  });\n\n  hljs.debugMode = function() { SAFE_MODE = false; };\n  hljs.safeMode = function() { SAFE_MODE = true; };\n  hljs.versionString = version;\n\n  for (const key in MODES) {\n    // @ts-ignore\n    if (typeof MODES[key] === \"object\") {\n      // @ts-ignore\n      deepFreezeEs6(MODES[key]);\n    }\n  }\n\n  // merge all the modes/regexs into our main object\n  Object.assign(hljs, MODES);\n\n  // built-in plugins, likely to be moved out of core in the future\n  hljs.addPlugin(brPlugin); // slated to be removed in v11\n  hljs.addPlugin(mergeHTMLPlugin);\n  hljs.addPlugin(tabReplacePlugin);\n  return hljs;\n};\n\n// export an \"instance\" of the highlighter\nvar highlight = HLJS({});\n\nmodule.exports = highlight;\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(function () {\n  'use strict';\n\n  const highlightJs = require('highlight.js/lib/core');\n\n  highlightJs.registerLanguage('asciidoc', require('highlight.js/lib/languages/asciidoc'));\n  highlightJs.registerLanguage('bash', require('highlight.js/lib/languages/bash'));\n  highlightJs.registerLanguage('css', require('highlight.js/lib/languages/css'));\n  highlightJs.registerLanguage('diff', require('highlight.js/lib/languages/diff'));\n  highlightJs.registerLanguage('dockerfile', require('highlight.js/lib/languages/dockerfile'));\n  highlightJs.registerLanguage('dos', require('highlight.js/lib/languages/dos'));\n  highlightJs.registerLanguage('gradle', require('highlight.js/lib/languages/gradle'));\n  highlightJs.registerLanguage('groovy', require('highlight.js/lib/languages/groovy'));\n  highlightJs.registerLanguage('http', require('highlight.js/lib/languages/http'));\n  highlightJs.registerLanguage('java', require('highlight.js/lib/languages/java'));\n  highlightJs.registerLanguage('javascript',require('highlight.js/lib/languages/javascript'));\n  highlightJs.registerLanguage('json', require('highlight.js/lib/languages/json'));\n  highlightJs.registerLanguage('kotlin', require('highlight.js/lib/languages/kotlin'));\n  highlightJs.registerLanguage('markdown', require('highlight.js/lib/languages/markdown'));\n  highlightJs.registerLanguage('nix', require('highlight.js/lib/languages/nix'));\n  highlightJs.registerLanguage('powershell', require('highlight.js/lib/languages/powershell'));\n  highlightJs.registerLanguage('properties', require('highlight.js/lib/languages/properties'));\n  highlightJs.registerLanguage('ruby', require('highlight.js/lib/languages/ruby'));\n  highlightJs.registerLanguage('scala', require('highlight.js/lib/languages/scala'));\n  highlightJs.registerLanguage('shell', require('highlight.js/lib/languages/shell'));\n  highlightJs.registerLanguage('sql', require('highlight.js/lib/languages/sql'));\n  highlightJs.registerLanguage('xml', require('highlight.js/lib/languages/xml'));\n  highlightJs.registerLanguage('yaml', require('highlight.js/lib/languages/yaml'));\n\n  highlightJs.configure({ignoreUnescapedHTML: true});\n\n  for(const codeElement of document.querySelectorAll('pre.highlight > code')) {\n    highlightJs.highlightBlock(codeElement);\n  }\n\n})();\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: AsciiDoc\nRequires: xml.js\nAuthor: Dan Allen \nWebsite: http://asciidoc.org\nDescription: A semantic, text-based document format that can be exported to HTML, DocBook and other backends.\nCategory: markup\n*/\n\n/** @type LanguageFn */\nfunction asciidoc(hljs) {\n  const HORIZONTAL_RULE = {\n    begin: '^\\'{3,}[ \\\\t]*$',\n    relevance: 10\n  };\n  const ESCAPED_FORMATTING = [\n    // escaped constrained formatting marks (i.e., \\* \\_ or \\`)\n    {\n      begin: /\\\\[*_`]/\n    },\n    // escaped unconstrained formatting marks (i.e., \\\\** \\\\__ or \\\\``)\n    // must ignore until the next formatting marks\n    // this rule might not be 100% compliant with Asciidoctor 2.0 but we are entering undefined behavior territory...\n    {\n      begin: /\\\\\\\\\\*{2}[^\\n]*?\\*{2}/\n    },\n    {\n      begin: /\\\\\\\\_{2}[^\\n]*_{2}/\n    },\n    {\n      begin: /\\\\\\\\`{2}[^\\n]*`{2}/\n    },\n    // guard: constrained formatting mark may not be preceded by \":\", \";\" or\n    // \"}\". match these so the constrained rule doesn't see them\n    {\n      begin: /[:;}][*_`](?![*_`])/\n    }\n  ];\n  const STRONG = [\n    // inline unconstrained strong (single line)\n    {\n      className: 'strong',\n      begin: /\\*{2}([^\\n]+?)\\*{2}/\n    },\n    // inline unconstrained strong (multi-line)\n    {\n      className: 'strong',\n      begin: concat(\n        /\\*\\*/,\n        /((\\*(?!\\*)|\\\\[^\\n]|[^*\\n\\\\])+\\n)+/,\n        /(\\*(?!\\*)|\\\\[^\\n]|[^*\\n\\\\])*/,\n        /\\*\\*/\n      ),\n      relevance: 0\n    },\n    // inline constrained strong (single line)\n    {\n      className: 'strong',\n      // must not precede or follow a word character\n      begin: /\\B\\*(\\S|\\S[^\\n]*?\\S)\\*(?!\\w)/\n    },\n    // inline constrained strong (multi-line)\n    {\n      className: 'strong',\n      // must not precede or follow a word character\n      begin: /\\*[^\\s]([^\\n]+\\n)+([^\\n]+)\\*/\n    }\n  ];\n  const EMPHASIS = [\n    // inline unconstrained emphasis (single line)\n    {\n      className: 'emphasis',\n      begin: /_{2}([^\\n]+?)_{2}/\n    },\n    // inline unconstrained emphasis (multi-line)\n    {\n      className: 'emphasis',\n      begin: concat(\n        /__/,\n        /((_(?!_)|\\\\[^\\n]|[^_\\n\\\\])+\\n)+/,\n        /(_(?!_)|\\\\[^\\n]|[^_\\n\\\\])*/,\n        /__/\n      ),\n      relevance: 0\n    },\n    // inline constrained emphasis (single line)\n    {\n      className: 'emphasis',\n      // must not precede or follow a word character\n      begin: /\\b_(\\S|\\S[^\\n]*?\\S)_(?!\\w)/\n    },\n    // inline constrained emphasis (multi-line)\n    {\n      className: 'emphasis',\n      // must not precede or follow a word character\n      begin: /_[^\\s]([^\\n]+\\n)+([^\\n]+)_/\n    },\n    // inline constrained emphasis using single quote (legacy)\n    {\n      className: 'emphasis',\n      // must not follow a word character or be followed by a single quote or space\n      begin: '\\\\B\\'(?![\\'\\\\s])',\n      end: '(\\\\n{2}|\\')',\n      // allow escaped single quote followed by word char\n      contains: [{\n        begin: '\\\\\\\\\\'\\\\w',\n        relevance: 0\n      }],\n      relevance: 0\n    }\n  ];\n  const ADMONITION = {\n    className: 'symbol',\n    begin: '^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\\\s+',\n    relevance: 10\n  };\n  const BULLET_LIST = {\n    className: 'bullet',\n    begin: '^(\\\\*+|-+|\\\\.+|[^\\\\n]+?::)\\\\s+'\n  };\n\n  return {\n    name: 'AsciiDoc',\n    aliases: ['adoc'],\n    contains: [\n      // block comment\n      hljs.COMMENT(\n        '^/{4,}\\\\n',\n        '\\\\n/{4,}$',\n        // can also be done as...\n        // '^/{4,}$',\n        // '^/{4,}$',\n        {\n          relevance: 10\n        }\n      ),\n      // line comment\n      hljs.COMMENT(\n        '^//',\n        '$',\n        {\n          relevance: 0\n        }\n      ),\n      // title\n      {\n        className: 'title',\n        begin: '^\\\\.\\\\w.*$'\n      },\n      // example, admonition & sidebar blocks\n      {\n        begin: '^[=\\\\*]{4,}\\\\n',\n        end: '\\\\n^[=\\\\*]{4,}$',\n        relevance: 10\n      },\n      // headings\n      {\n        className: 'section',\n        relevance: 10,\n        variants: [\n          {\n            begin: '^(={1,6})[ \\t].+?([ \\t]\\\\1)?$'\n          },\n          {\n            begin: '^[^\\\\[\\\\]\\\\n]+?\\\\n[=\\\\-~\\\\^\\\\+]{2,}$'\n          }\n        ]\n      },\n      // document attributes\n      {\n        className: 'meta',\n        begin: '^:.+?:',\n        end: '\\\\s',\n        excludeEnd: true,\n        relevance: 10\n      },\n      // block attributes\n      {\n        className: 'meta',\n        begin: '^\\\\[.+?\\\\]$',\n        relevance: 0\n      },\n      // quoteblocks\n      {\n        className: 'quote',\n        begin: '^_{4,}\\\\n',\n        end: '\\\\n_{4,}$',\n        relevance: 10\n      },\n      // listing and literal blocks\n      {\n        className: 'code',\n        begin: '^[\\\\-\\\\.]{4,}\\\\n',\n        end: '\\\\n[\\\\-\\\\.]{4,}$',\n        relevance: 10\n      },\n      // passthrough blocks\n      {\n        begin: '^\\\\+{4,}\\\\n',\n        end: '\\\\n\\\\+{4,}$',\n        contains: [{\n          begin: '<',\n          end: '>',\n          subLanguage: 'xml',\n          relevance: 0\n        }],\n        relevance: 10\n      },\n\n      BULLET_LIST,\n      ADMONITION,\n      ...ESCAPED_FORMATTING,\n      ...STRONG,\n      ...EMPHASIS,\n\n      // inline smart quotes\n      {\n        className: 'string',\n        variants: [\n          {\n            begin: \"``.+?''\"\n          },\n          {\n            begin: \"`.+?'\"\n          }\n        ]\n      },\n      // inline unconstrained emphasis\n      {\n        className: 'code',\n        begin: /`{2}/,\n        end: /(\\n{2}|`{2})/\n      },\n      // inline code snippets (TODO should get same treatment as strong and emphasis)\n      {\n        className: 'code',\n        begin: '(`.+?`|\\\\+.+?\\\\+)',\n        relevance: 0\n      },\n      // indented literal block\n      {\n        className: 'code',\n        begin: '^[ \\\\t]',\n        end: '$',\n        relevance: 0\n      },\n      HORIZONTAL_RULE,\n      // images and links\n      {\n        begin: '(link:)?(http|https|ftp|file|irc|image:?):\\\\S+?\\\\[[^[]*?\\\\]',\n        returnBegin: true,\n        contains: [\n          {\n            begin: '(link|image:?):',\n            relevance: 0\n          },\n          {\n            className: 'link',\n            begin: '\\\\w',\n            end: '[^\\\\[]+',\n            relevance: 0\n          },\n          {\n            className: 'string',\n            begin: '\\\\[',\n            end: '\\\\]',\n            excludeBegin: true,\n            excludeEnd: true,\n            relevance: 0\n          }\n        ],\n        relevance: 10\n      }\n    ]\n  };\n}\n\nmodule.exports = asciidoc;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: Bash\nAuthor: vah \nContributrors: Benjamin Pannell \nWebsite: https://www.gnu.org/software/bash/\nCategory: common\n*/\n\n/** @type LanguageFn */\nfunction bash(hljs) {\n  const VAR = {};\n  const BRACED_VAR = {\n    begin: /\\$\\{/,\n    end:/\\}/,\n    contains: [\n      \"self\",\n      {\n        begin: /:-/,\n        contains: [ VAR ]\n      } // default values\n    ]\n  };\n  Object.assign(VAR,{\n    className: 'variable',\n    variants: [\n      {begin: concat(/\\$[\\w\\d#@][\\w\\d_]*/,\n        // negative look-ahead tries to avoid matching patterns that are not\n        // Perl at all like $ident$, @ident@, etc.\n        `(?![\\\\w\\\\d])(?![$])`) },\n      BRACED_VAR\n    ]\n  });\n\n  const SUBST = {\n    className: 'subst',\n    begin: /\\$\\(/, end: /\\)/,\n    contains: [hljs.BACKSLASH_ESCAPE]\n  };\n  const HERE_DOC = {\n    begin: /<<-?\\s*(?=\\w+)/,\n    starts: {\n      contains: [\n        hljs.END_SAME_AS_BEGIN({\n          begin: /(\\w+)/,\n          end: /(\\w+)/,\n          className: 'string'\n        })\n      ]\n    }\n  };\n  const QUOTE_STRING = {\n    className: 'string',\n    begin: /\"/, end: /\"/,\n    contains: [\n      hljs.BACKSLASH_ESCAPE,\n      VAR,\n      SUBST\n    ]\n  };\n  SUBST.contains.push(QUOTE_STRING);\n  const ESCAPED_QUOTE = {\n    className: '',\n    begin: /\\\\\"/\n\n  };\n  const APOS_STRING = {\n    className: 'string',\n    begin: /'/, end: /'/\n  };\n  const ARITHMETIC = {\n    begin: /\\$\\(\\(/,\n    end: /\\)\\)/,\n    contains: [\n      { begin: /\\d+#[0-9a-f]+/, className: \"number\" },\n      hljs.NUMBER_MODE,\n      VAR\n    ]\n  };\n  const SH_LIKE_SHELLS = [\n    \"fish\",\n    \"bash\",\n    \"zsh\",\n    \"sh\",\n    \"csh\",\n    \"ksh\",\n    \"tcsh\",\n    \"dash\",\n    \"scsh\",\n  ];\n  const KNOWN_SHEBANG = hljs.SHEBANG({\n    binary: `(${SH_LIKE_SHELLS.join(\"|\")})`,\n    relevance: 10\n  });\n  const FUNCTION = {\n    className: 'function',\n    begin: /\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,\n    returnBegin: true,\n    contains: [hljs.inherit(hljs.TITLE_MODE, {begin: /\\w[\\w\\d_]*/})],\n    relevance: 0\n  };\n\n  return {\n    name: 'Bash',\n    aliases: ['sh', 'zsh'],\n    keywords: {\n      $pattern: /\\b[a-z._-]+\\b/,\n      keyword:\n        'if then else elif fi for while in do done case esac function',\n      literal:\n        'true false',\n      built_in:\n        // Shell built-ins\n        // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html\n        'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' +\n        'trap umask unset ' +\n        // Bash built-ins\n        'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' +\n        'read readarray source type typeset ulimit unalias ' +\n        // Shell modifiers\n        'set shopt ' +\n        // Zsh built-ins\n        'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' +\n        'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' +\n        'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' +\n        'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' +\n        'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' +\n        'zpty zregexparse zsocket zstyle ztcp'\n    },\n    contains: [\n      KNOWN_SHEBANG, // to catch known shells and boost relevancy\n      hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang\n      FUNCTION,\n      ARITHMETIC,\n      hljs.HASH_COMMENT_MODE,\n      HERE_DOC,\n      QUOTE_STRING,\n      ESCAPED_QUOTE,\n      APOS_STRING,\n      VAR\n    ]\n  };\n}\n\nmodule.exports = bash;\n","const MODES = (hljs) => {\n  return {\n    IMPORTANT: {\n      className: 'meta',\n      begin: '!important'\n    },\n    HEXCOLOR: {\n      className: 'number',\n      begin: '#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})'\n    },\n    ATTRIBUTE_SELECTOR_MODE: {\n      className: 'selector-attr',\n      begin: /\\[/,\n      end: /\\]/,\n      illegal: '$',\n      contains: [\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE\n      ]\n    }\n  };\n};\n\nconst TAGS = [\n  'a',\n  'abbr',\n  'address',\n  'article',\n  'aside',\n  'audio',\n  'b',\n  'blockquote',\n  'body',\n  'button',\n  'canvas',\n  'caption',\n  'cite',\n  'code',\n  'dd',\n  'del',\n  'details',\n  'dfn',\n  'div',\n  'dl',\n  'dt',\n  'em',\n  'fieldset',\n  'figcaption',\n  'figure',\n  'footer',\n  'form',\n  'h1',\n  'h2',\n  'h3',\n  'h4',\n  'h5',\n  'h6',\n  'header',\n  'hgroup',\n  'html',\n  'i',\n  'iframe',\n  'img',\n  'input',\n  'ins',\n  'kbd',\n  'label',\n  'legend',\n  'li',\n  'main',\n  'mark',\n  'menu',\n  'nav',\n  'object',\n  'ol',\n  'p',\n  'q',\n  'quote',\n  'samp',\n  'section',\n  'span',\n  'strong',\n  'summary',\n  'sup',\n  'table',\n  'tbody',\n  'td',\n  'textarea',\n  'tfoot',\n  'th',\n  'thead',\n  'time',\n  'tr',\n  'ul',\n  'var',\n  'video'\n];\n\nconst MEDIA_FEATURES = [\n  'any-hover',\n  'any-pointer',\n  'aspect-ratio',\n  'color',\n  'color-gamut',\n  'color-index',\n  'device-aspect-ratio',\n  'device-height',\n  'device-width',\n  'display-mode',\n  'forced-colors',\n  'grid',\n  'height',\n  'hover',\n  'inverted-colors',\n  'monochrome',\n  'orientation',\n  'overflow-block',\n  'overflow-inline',\n  'pointer',\n  'prefers-color-scheme',\n  'prefers-contrast',\n  'prefers-reduced-motion',\n  'prefers-reduced-transparency',\n  'resolution',\n  'scan',\n  'scripting',\n  'update',\n  'width',\n  // TODO: find a better solution?\n  'min-width',\n  'max-width',\n  'min-height',\n  'max-height'\n];\n\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes\nconst PSEUDO_CLASSES = [\n  'active',\n  'any-link',\n  'blank',\n  'checked',\n  'current',\n  'default',\n  'defined',\n  'dir', // dir()\n  'disabled',\n  'drop',\n  'empty',\n  'enabled',\n  'first',\n  'first-child',\n  'first-of-type',\n  'fullscreen',\n  'future',\n  'focus',\n  'focus-visible',\n  'focus-within',\n  'has', // has()\n  'host', // host or host()\n  'host-context', // host-context()\n  'hover',\n  'indeterminate',\n  'in-range',\n  'invalid',\n  'is', // is()\n  'lang', // lang()\n  'last-child',\n  'last-of-type',\n  'left',\n  'link',\n  'local-link',\n  'not', // not()\n  'nth-child', // nth-child()\n  'nth-col', // nth-col()\n  'nth-last-child', // nth-last-child()\n  'nth-last-col', // nth-last-col()\n  'nth-last-of-type', //nth-last-of-type()\n  'nth-of-type', //nth-of-type()\n  'only-child',\n  'only-of-type',\n  'optional',\n  'out-of-range',\n  'past',\n  'placeholder-shown',\n  'read-only',\n  'read-write',\n  'required',\n  'right',\n  'root',\n  'scope',\n  'target',\n  'target-within',\n  'user-invalid',\n  'valid',\n  'visited',\n  'where' // where()\n];\n\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements\nconst PSEUDO_ELEMENTS = [\n  'after',\n  'backdrop',\n  'before',\n  'cue',\n  'cue-region',\n  'first-letter',\n  'first-line',\n  'grammar-error',\n  'marker',\n  'part',\n  'placeholder',\n  'selection',\n  'slotted',\n  'spelling-error'\n];\n\nconst ATTRIBUTES = [\n  'align-content',\n  'align-items',\n  'align-self',\n  'animation',\n  'animation-delay',\n  'animation-direction',\n  'animation-duration',\n  'animation-fill-mode',\n  'animation-iteration-count',\n  'animation-name',\n  'animation-play-state',\n  'animation-timing-function',\n  'auto',\n  'backface-visibility',\n  'background',\n  'background-attachment',\n  'background-clip',\n  'background-color',\n  'background-image',\n  'background-origin',\n  'background-position',\n  'background-repeat',\n  'background-size',\n  'border',\n  'border-bottom',\n  'border-bottom-color',\n  'border-bottom-left-radius',\n  'border-bottom-right-radius',\n  'border-bottom-style',\n  'border-bottom-width',\n  'border-collapse',\n  'border-color',\n  'border-image',\n  'border-image-outset',\n  'border-image-repeat',\n  'border-image-slice',\n  'border-image-source',\n  'border-image-width',\n  'border-left',\n  'border-left-color',\n  'border-left-style',\n  'border-left-width',\n  'border-radius',\n  'border-right',\n  'border-right-color',\n  'border-right-style',\n  'border-right-width',\n  'border-spacing',\n  'border-style',\n  'border-top',\n  'border-top-color',\n  'border-top-left-radius',\n  'border-top-right-radius',\n  'border-top-style',\n  'border-top-width',\n  'border-width',\n  'bottom',\n  'box-decoration-break',\n  'box-shadow',\n  'box-sizing',\n  'break-after',\n  'break-before',\n  'break-inside',\n  'caption-side',\n  'clear',\n  'clip',\n  'clip-path',\n  'color',\n  'column-count',\n  'column-fill',\n  'column-gap',\n  'column-rule',\n  'column-rule-color',\n  'column-rule-style',\n  'column-rule-width',\n  'column-span',\n  'column-width',\n  'columns',\n  'content',\n  'counter-increment',\n  'counter-reset',\n  'cursor',\n  'direction',\n  'display',\n  'empty-cells',\n  'filter',\n  'flex',\n  'flex-basis',\n  'flex-direction',\n  'flex-flow',\n  'flex-grow',\n  'flex-shrink',\n  'flex-wrap',\n  'float',\n  'font',\n  'font-display',\n  'font-family',\n  'font-feature-settings',\n  'font-kerning',\n  'font-language-override',\n  'font-size',\n  'font-size-adjust',\n  'font-smoothing',\n  'font-stretch',\n  'font-style',\n  'font-variant',\n  'font-variant-ligatures',\n  'font-variation-settings',\n  'font-weight',\n  'height',\n  'hyphens',\n  'icon',\n  'image-orientation',\n  'image-rendering',\n  'image-resolution',\n  'ime-mode',\n  'inherit',\n  'initial',\n  'justify-content',\n  'left',\n  'letter-spacing',\n  'line-height',\n  'list-style',\n  'list-style-image',\n  'list-style-position',\n  'list-style-type',\n  'margin',\n  'margin-bottom',\n  'margin-left',\n  'margin-right',\n  'margin-top',\n  'marks',\n  'mask',\n  'max-height',\n  'max-width',\n  'min-height',\n  'min-width',\n  'nav-down',\n  'nav-index',\n  'nav-left',\n  'nav-right',\n  'nav-up',\n  'none',\n  'normal',\n  'object-fit',\n  'object-position',\n  'opacity',\n  'order',\n  'orphans',\n  'outline',\n  'outline-color',\n  'outline-offset',\n  'outline-style',\n  'outline-width',\n  'overflow',\n  'overflow-wrap',\n  'overflow-x',\n  'overflow-y',\n  'padding',\n  'padding-bottom',\n  'padding-left',\n  'padding-right',\n  'padding-top',\n  'page-break-after',\n  'page-break-before',\n  'page-break-inside',\n  'perspective',\n  'perspective-origin',\n  'pointer-events',\n  'position',\n  'quotes',\n  'resize',\n  'right',\n  'src', // @font-face\n  'tab-size',\n  'table-layout',\n  'text-align',\n  'text-align-last',\n  'text-decoration',\n  'text-decoration-color',\n  'text-decoration-line',\n  'text-decoration-style',\n  'text-indent',\n  'text-overflow',\n  'text-rendering',\n  'text-shadow',\n  'text-transform',\n  'text-underline-position',\n  'top',\n  'transform',\n  'transform-origin',\n  'transform-style',\n  'transition',\n  'transition-delay',\n  'transition-duration',\n  'transition-property',\n  'transition-timing-function',\n  'unicode-bidi',\n  'vertical-align',\n  'visibility',\n  'white-space',\n  'widows',\n  'width',\n  'word-break',\n  'word-spacing',\n  'word-wrap',\n  'z-index'\n  // reverse makes sure longer attributes `font-weight` are matched fully\n  // instead of getting false positives on say `font`\n].reverse();\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: CSS\nCategory: common, css\nWebsite: https://developer.mozilla.org/en-US/docs/Web/CSS\n*/\n\n/** @type LanguageFn */\nfunction css(hljs) {\n  const modes = MODES(hljs);\n  const FUNCTION_DISPATCH = {\n    className: \"built_in\",\n    begin: /[\\w-]+(?=\\()/\n  };\n  const VENDOR_PREFIX = {\n    begin: /-(webkit|moz|ms|o)-(?=[a-z])/\n  };\n  const AT_MODIFIERS = \"and or not only\";\n  const AT_PROPERTY_RE = /@-?\\w[\\w]*(-\\w+)*/; // @-webkit-keyframes\n  const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';\n  const STRINGS = [\n    hljs.APOS_STRING_MODE,\n    hljs.QUOTE_STRING_MODE\n  ];\n\n  return {\n    name: 'CSS',\n    case_insensitive: true,\n    illegal: /[=|'\\$]/,\n    keywords: {\n      keyframePosition: \"from to\"\n    },\n    classNameAliases: {\n      // for visual continuity with `tag {}` and because we\n      // don't have a great class for this?\n      keyframePosition: \"selector-tag\"\n    },\n    contains: [\n      hljs.C_BLOCK_COMMENT_MODE,\n      VENDOR_PREFIX,\n      // to recognize keyframe 40% etc which are outside the scope of our\n      // attribute value mode\n      hljs.CSS_NUMBER_MODE,\n      {\n        className: 'selector-id',\n        begin: /#[A-Za-z0-9_-]+/,\n        relevance: 0\n      },\n      {\n        className: 'selector-class',\n        begin: '\\\\.' + IDENT_RE,\n        relevance: 0\n      },\n      modes.ATTRIBUTE_SELECTOR_MODE,\n      {\n        className: 'selector-pseudo',\n        variants: [\n          {\n            begin: ':(' + PSEUDO_CLASSES.join('|') + ')'\n          },\n          {\n            begin: '::(' + PSEUDO_ELEMENTS.join('|') + ')'\n          }\n        ]\n      },\n      // we may actually need this (12/2020)\n      // { // pseudo-selector params\n      //   begin: /\\(/,\n      //   end: /\\)/,\n      //   contains: [ hljs.CSS_NUMBER_MODE ]\n      // },\n      {\n        className: 'attribute',\n        begin: '\\\\b(' + ATTRIBUTES.join('|') + ')\\\\b'\n      },\n      // attribute values\n      {\n        begin: ':',\n        end: '[;}]',\n        contains: [\n          modes.HEXCOLOR,\n          modes.IMPORTANT,\n          hljs.CSS_NUMBER_MODE,\n          ...STRINGS,\n          // needed to highlight these as strings and to avoid issues with\n          // illegal characters that might be inside urls that would tigger the\n          // languages illegal stack\n          {\n            begin: /(url|data-uri)\\(/,\n            end: /\\)/,\n            relevance: 0, // from keywords\n            keywords: {\n              built_in: \"url data-uri\"\n            },\n            contains: [\n              {\n                className: \"string\",\n                // any character other than `)` as in `url()` will be the start\n                // of a string, which ends with `)` (from the parent mode)\n                begin: /[^)]/,\n                endsWithParent: true,\n                excludeEnd: true\n              }\n            ]\n          },\n          FUNCTION_DISPATCH\n        ]\n      },\n      {\n        begin: lookahead(/@/),\n        end: '[{;]',\n        relevance: 0,\n        illegal: /:/, // break on Less variables @var: ...\n        contains: [\n          {\n            className: 'keyword',\n            begin: AT_PROPERTY_RE\n          },\n          {\n            begin: /\\s/,\n            endsWithParent: true,\n            excludeEnd: true,\n            relevance: 0,\n            keywords: {\n              $pattern: /[a-z-]+/,\n              keyword: AT_MODIFIERS,\n              attribute: MEDIA_FEATURES.join(\" \")\n            },\n            contains: [\n              {\n                begin: /[a-z-]+(?=:)/,\n                className: \"attribute\"\n              },\n              ...STRINGS,\n              hljs.CSS_NUMBER_MODE\n            ]\n          }\n        ]\n      },\n      {\n        className: 'selector-tag',\n        begin: '\\\\b(' + TAGS.join('|') + ')\\\\b'\n      }\n    ]\n  };\n}\n\nmodule.exports = css;\n","/*\nLanguage: Diff\nDescription: Unified and context diff\nAuthor: Vasily Polovnyov \nWebsite: https://www.gnu.org/software/diffutils/\nCategory: common\n*/\n\n/** @type LanguageFn */\nfunction diff(hljs) {\n  return {\n    name: 'Diff',\n    aliases: ['patch'],\n    contains: [\n      {\n        className: 'meta',\n        relevance: 10,\n        variants: [\n          {\n            begin: /^@@ +-\\d+,\\d+ +\\+\\d+,\\d+ +@@/\n          },\n          {\n            begin: /^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$/\n          },\n          {\n            begin: /^--- +\\d+,\\d+ +----$/\n          }\n        ]\n      },\n      {\n        className: 'comment',\n        variants: [\n          {\n            begin: /Index: /,\n            end: /$/\n          },\n          {\n            begin: /^index/,\n            end: /$/\n          },\n          {\n            begin: /={3,}/,\n            end: /$/\n          },\n          {\n            begin: /^-{3}/,\n            end: /$/\n          },\n          {\n            begin: /^\\*{3} /,\n            end: /$/\n          },\n          {\n            begin: /^\\+{3}/,\n            end: /$/\n          },\n          {\n            begin: /^\\*{15}$/\n          },\n          {\n            begin: /^diff --git/,\n            end: /$/\n          }\n        ]\n      },\n      {\n        className: 'addition',\n        begin: /^\\+/,\n        end: /$/\n      },\n      {\n        className: 'deletion',\n        begin: /^-/,\n        end: /$/\n      },\n      {\n        className: 'addition',\n        begin: /^!/,\n        end: /$/\n      }\n    ]\n  };\n}\n\nmodule.exports = diff;\n","/*\nLanguage: Dockerfile\nRequires: bash.js\nAuthor: Alexis Hénaut \nDescription: language definition for Dockerfile files\nWebsite: https://docs.docker.com/engine/reference/builder/\nCategory: config\n*/\n\n/** @type LanguageFn */\nfunction dockerfile(hljs) {\n  return {\n    name: 'Dockerfile',\n    aliases: ['docker'],\n    case_insensitive: true,\n    keywords: 'from maintainer expose env arg user onbuild stopsignal',\n    contains: [\n      hljs.HASH_COMMENT_MODE,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      hljs.NUMBER_MODE,\n      {\n        beginKeywords: 'run cmd entrypoint volume add copy workdir label healthcheck shell',\n        starts: {\n          end: /[^\\\\]$/,\n          subLanguage: 'bash'\n        }\n      }\n    ],\n    illegal: '\nContributors: Anton Kochkov \nWebsite: https://en.wikipedia.org/wiki/Batch_file\n*/\n\n/** @type LanguageFn */\nfunction dos(hljs) {\n  const COMMENT = hljs.COMMENT(\n    /^\\s*@?rem\\b/, /$/,\n    {\n      relevance: 10\n    }\n  );\n  const LABEL = {\n    className: 'symbol',\n    begin: '^\\\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\\\s+label)',\n    relevance: 0\n  };\n  return {\n    name: 'Batch file (DOS)',\n    aliases: [\n      'bat',\n      'cmd'\n    ],\n    case_insensitive: true,\n    illegal: /\\/\\*/,\n    keywords: {\n      keyword:\n        'if else goto for in do call exit not exist errorlevel defined ' +\n        'equ neq lss leq gtr geq',\n      built_in:\n        'prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux ' +\n        'shift cd dir echo setlocal endlocal set pause copy ' +\n        'append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color ' +\n        'comp compact convert date dir diskcomp diskcopy doskey erase fs ' +\n        'find findstr format ftype graftabl help keyb label md mkdir mode more move path ' +\n        'pause print popd pushd promt rd recover rem rename replace restore rmdir shift ' +\n        'sort start subst time title tree type ver verify vol ' +\n        // winutils\n        'ping net ipconfig taskkill xcopy ren del'\n    },\n    contains: [\n      {\n        className: 'variable',\n        begin: /%%[^ ]|%[^ ]+?%|![^ ]+?!/\n      },\n      {\n        className: 'function',\n        begin: LABEL.begin,\n        end: 'goto:eof',\n        contains: [\n          hljs.inherit(hljs.TITLE_MODE, {\n            begin: '([_a-zA-Z]\\\\w*\\\\.)*([_a-zA-Z]\\\\w*:)?[_a-zA-Z]\\\\w*'\n          }),\n          COMMENT\n        ]\n      },\n      {\n        className: 'number',\n        begin: '\\\\b\\\\d+',\n        relevance: 0\n      },\n      COMMENT\n    ]\n  };\n}\n\nmodule.exports = dos;\n","/*\nLanguage: Gradle\nDescription: Gradle is an open-source build automation tool focused on flexibility and performance.\nWebsite: https://gradle.org\nAuthor: Damian Mee \n*/\n\nfunction gradle(hljs) {\n  return {\n    name: 'Gradle',\n    case_insensitive: true,\n    keywords: {\n      keyword:\n        'task project allprojects subprojects artifacts buildscript configurations ' +\n        'dependencies repositories sourceSets description delete from into include ' +\n        'exclude source classpath destinationDir includes options sourceCompatibility ' +\n        'targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant ' +\n        'def abstract break case catch continue default do else extends final finally ' +\n        'for if implements instanceof native new private protected public return static ' +\n        'switch synchronized throw throws transient try volatile while strictfp package ' +\n        'import false null super this true antlrtask checkstyle codenarc copy boolean ' +\n        'byte char class double float int interface long short void compile runTime ' +\n        'file fileTree abs any append asList asWritable call collect compareTo count ' +\n        'div dump each eachByte eachFile eachLine every find findAll flatten getAt ' +\n        'getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods ' +\n        'isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter ' +\n        'newReader newWriter next plus pop power previous print println push putAt read ' +\n        'readBytes readLines reverse reverseEach round size sort splitEachLine step subMap ' +\n        'times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader ' +\n        'withStream withWriter withWriterAppend write writeLine'\n    },\n    contains: [\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      hljs.NUMBER_MODE,\n      hljs.REGEXP_MODE\n\n    ]\n  };\n}\n\nmodule.exports = gradle;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\n Language: Groovy\n Author: Guillaume Laforge \n Description: Groovy programming language implementation inspired from Vsevolod's Java mode\n Website: https://groovy-lang.org\n */\n\nfunction variants(variants, obj = {}) {\n  obj.variants = variants;\n  return obj;\n}\n\nfunction groovy(hljs) {\n  const IDENT_RE = '[A-Za-z0-9_$]+';\n  const COMMENT = variants([\n    hljs.C_LINE_COMMENT_MODE,\n    hljs.C_BLOCK_COMMENT_MODE,\n    hljs.COMMENT(\n      '/\\\\*\\\\*',\n      '\\\\*/',\n      {\n        relevance: 0,\n        contains: [\n          {\n            // eat up @'s in emails to prevent them to be recognized as doctags\n            begin: /\\w+@/,\n            relevance: 0\n          },\n          {\n            className: 'doctag',\n            begin: '@[A-Za-z]+'\n          }\n        ]\n      }\n    )\n  ]);\n  const REGEXP = {\n    className: 'regexp',\n    begin: /~?\\/[^\\/\\n]+\\//,\n    contains: [ hljs.BACKSLASH_ESCAPE ]\n  };\n  const NUMBER = variants([\n    hljs.BINARY_NUMBER_MODE,\n    hljs.C_NUMBER_MODE\n  ]);\n  const STRING = variants([\n    {\n      begin: /\"\"\"/,\n      end: /\"\"\"/\n    },\n    {\n      begin: /'''/,\n      end: /'''/\n    },\n    {\n      begin: \"\\\\$/\",\n      end: \"/\\\\$\",\n      relevance: 10\n    },\n    hljs.APOS_STRING_MODE,\n    hljs.QUOTE_STRING_MODE\n  ],\n  {\n    className: \"string\"\n  }\n  );\n\n  return {\n    name: 'Groovy',\n    keywords: {\n      built_in: 'this super',\n      literal: 'true false null',\n      keyword:\n            'byte short char int long boolean float double void ' +\n            // groovy specific keywords\n            'def as in assert trait ' +\n            // common keywords with Java\n            'abstract static volatile transient public private protected synchronized final ' +\n            'class interface enum if else for while switch case break default continue ' +\n            'throw throws try catch finally implements extends new import package return instanceof'\n    },\n    contains: [\n      hljs.SHEBANG({\n        binary: \"groovy\",\n        relevance: 10\n      }),\n      COMMENT,\n      STRING,\n      REGEXP,\n      NUMBER,\n      {\n        className: 'class',\n        beginKeywords: 'class interface trait enum',\n        end: /\\{/,\n        illegal: ':',\n        contains: [\n          {\n            beginKeywords: 'extends implements'\n          },\n          hljs.UNDERSCORE_TITLE_MODE\n        ]\n      },\n      {\n        className: 'meta',\n        begin: '@[A-Za-z]+',\n        relevance: 0\n      },\n      {\n        // highlight map keys and named parameters as attrs\n        className: 'attr',\n        begin: IDENT_RE + '[ \\t]*:',\n        relevance: 0\n      },\n      {\n        // catch middle element of the ternary operator\n        // to avoid highlight it as a label, named parameter, or map key\n        begin: /\\?/,\n        end: /:/,\n        relevance: 0,\n        contains: [\n          COMMENT,\n          STRING,\n          REGEXP,\n          NUMBER,\n          'self'\n        ]\n      },\n      {\n        // highlight labeled statements\n        className: 'symbol',\n        begin: '^[ \\t]*' + lookahead(IDENT_RE + ':'),\n        excludeBegin: true,\n        end: IDENT_RE + ':',\n        relevance: 0\n      }\n    ],\n    illegal: /#|<\\//\n  };\n}\n\nmodule.exports = groovy;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: HTTP\nDescription: HTTP request and response headers with automatic body highlighting\nAuthor: Ivan Sagalaev \nCategory: common, protocols\nWebsite: https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview\n*/\n\nfunction http(hljs) {\n  const VERSION = 'HTTP/(2|1\\\\.[01])';\n  const HEADER_NAME = /[A-Za-z][A-Za-z0-9-]*/;\n  const HEADER = {\n    className: 'attribute',\n    begin: concat('^', HEADER_NAME, '(?=\\\\:\\\\s)'),\n    starts: {\n      contains: [\n        {\n          className: \"punctuation\",\n          begin: /: /,\n          relevance: 0,\n          starts: {\n            end: '$',\n            relevance: 0\n          }\n        }\n      ]\n    }\n  };\n  const HEADERS_AND_BODY = [\n    HEADER,\n    {\n      begin: '\\\\n\\\\n',\n      starts: { subLanguage: [], endsWithParent: true }\n    }\n  ];\n\n  return {\n    name: 'HTTP',\n    aliases: ['https'],\n    illegal: /\\S/,\n    contains: [\n      // response\n      {\n        begin: '^(?=' + VERSION + \" \\\\d{3})\",\n        end: /$/,\n        contains: [\n          {\n            className: \"meta\",\n            begin: VERSION\n          },\n          {\n            className: 'number', begin: '\\\\b\\\\d{3}\\\\b'\n          }\n        ],\n        starts: {\n          end: /\\b\\B/,\n          illegal: /\\S/,\n          contains: HEADERS_AND_BODY\n        }\n      },\n      // request\n      {\n        begin: '(?=^[A-Z]+ (.*?) ' + VERSION + '$)',\n        end: /$/,\n        contains: [\n          {\n            className: 'string',\n            begin: ' ',\n            end: ' ',\n            excludeBegin: true,\n            excludeEnd: true\n          },\n          {\n            className: \"meta\",\n            begin: VERSION\n          },\n          {\n            className: 'keyword',\n            begin: '[A-Z]+'\n          }\n        ],\n        starts: {\n          end: /\\b\\B/,\n          illegal: /\\S/,\n          contains: HEADERS_AND_BODY\n        }\n      },\n      // to allow headers to work even without a preamble\n      hljs.inherit(HEADER, {\n        relevance: 0\n      })\n    ]\n  };\n}\n\nmodule.exports = http;\n","// https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10\nvar decimalDigits = '[0-9](_*[0-9])*';\nvar frac = `\\\\.(${decimalDigits})`;\nvar hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';\nvar NUMERIC = {\n  className: 'number',\n  variants: [\n    // DecimalFloatingPointLiteral\n    // including ExponentPart\n    { begin: `(\\\\b(${decimalDigits})((${frac})|\\\\.)?|(${frac}))` +\n      `[eE][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n    // excluding ExponentPart\n    { begin: `\\\\b(${decimalDigits})((${frac})[fFdD]?\\\\b|\\\\.([fFdD]\\\\b)?)` },\n    { begin: `(${frac})[fFdD]?\\\\b` },\n    { begin: `\\\\b(${decimalDigits})[fFdD]\\\\b` },\n\n    // HexadecimalFloatingPointLiteral\n    { begin: `\\\\b0[xX]((${hexDigits})\\\\.?|(${hexDigits})?\\\\.(${hexDigits}))` +\n      `[pP][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n\n    // DecimalIntegerLiteral\n    { begin: '\\\\b(0|[1-9](_*[0-9])*)[lL]?\\\\b' },\n\n    // HexIntegerLiteral\n    { begin: `\\\\b0[xX](${hexDigits})[lL]?\\\\b` },\n\n    // OctalIntegerLiteral\n    { begin: '\\\\b0(_*[0-7])*[lL]?\\\\b' },\n\n    // BinaryIntegerLiteral\n    { begin: '\\\\b0[bB][01](_*[01])*[lL]?\\\\b' },\n  ],\n  relevance: 0\n};\n\n/*\nLanguage: Java\nAuthor: Vsevolod Solovyov \nCategory: common, enterprise\nWebsite: https://www.java.com/\n*/\n\nfunction java(hljs) {\n  var JAVA_IDENT_RE = '[\\u00C0-\\u02B8a-zA-Z_$][\\u00C0-\\u02B8a-zA-Z_$0-9]*';\n  var GENERIC_IDENT_RE = JAVA_IDENT_RE + '(<' + JAVA_IDENT_RE + '(\\\\s*,\\\\s*' + JAVA_IDENT_RE + ')*>)?';\n  var KEYWORDS = 'false synchronized int abstract float private char boolean var static null if const ' +\n    'for true while long strictfp finally protected import native final void ' +\n    'enum else break transient catch instanceof byte super volatile case assert short ' +\n    'package default double public try this switch continue throws protected public private ' +\n    'module requires exports do';\n\n  var ANNOTATION = {\n    className: 'meta',\n    begin: '@' + JAVA_IDENT_RE,\n    contains: [\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [\"self\"] // allow nested () inside our annotation\n      },\n    ]\n  };\n  const NUMBER = NUMERIC;\n\n  return {\n    name: 'Java',\n    aliases: ['jsp'],\n    keywords: KEYWORDS,\n    illegal: /<\\/|#/,\n    contains: [\n      hljs.COMMENT(\n        '/\\\\*\\\\*',\n        '\\\\*/',\n        {\n          relevance: 0,\n          contains: [\n            {\n              // eat up @'s in emails to prevent them to be recognized as doctags\n              begin: /\\w+@/, relevance: 0\n            },\n            {\n              className: 'doctag',\n              begin: '@[A-Za-z]+'\n            }\n          ]\n        }\n      ),\n      // relevance boost\n      {\n        begin: /import java\\.[a-z]+\\./,\n        keywords: \"import\",\n        relevance: 2\n      },\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      {\n        className: 'class',\n        beginKeywords: 'class interface enum', end: /[{;=]/, excludeEnd: true,\n        // TODO: can this be removed somehow?\n        // an extra boost because Java is more popular than other languages with\n        // this same syntax feature (this is just to preserve our tests passing\n        // for now)\n        relevance: 1,\n        keywords: 'class interface enum',\n        illegal: /[:\"\\[\\]]/,\n        contains: [\n          { beginKeywords: 'extends implements' },\n          hljs.UNDERSCORE_TITLE_MODE\n        ]\n      },\n      {\n        // Expression keywords prevent 'keyword Name(...)' from being\n        // recognized as a function definition\n        beginKeywords: 'new throw return else',\n        relevance: 0\n      },\n      {\n        className: 'class',\n        begin: 'record\\\\s+' + hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n        returnBegin: true,\n        excludeEnd: true,\n        end: /[{;=]/,\n        keywords: KEYWORDS,\n        contains: [\n          { beginKeywords: \"record\" },\n          {\n            begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n            returnBegin: true,\n            relevance: 0,\n            contains: [hljs.UNDERSCORE_TITLE_MODE]\n          },\n          {\n            className: 'params',\n            begin: /\\(/, end: /\\)/,\n            keywords: KEYWORDS,\n            relevance: 0,\n            contains: [\n              hljs.C_BLOCK_COMMENT_MODE\n            ]\n          },\n          hljs.C_LINE_COMMENT_MODE,\n          hljs.C_BLOCK_COMMENT_MODE\n        ]\n      },\n      {\n        className: 'function',\n        begin: '(' + GENERIC_IDENT_RE + '\\\\s+)+' + hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(', returnBegin: true, end: /[{;=]/,\n        excludeEnd: true,\n        keywords: KEYWORDS,\n        contains: [\n          {\n            begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(', returnBegin: true,\n            relevance: 0,\n            contains: [hljs.UNDERSCORE_TITLE_MODE]\n          },\n          {\n            className: 'params',\n            begin: /\\(/, end: /\\)/,\n            keywords: KEYWORDS,\n            relevance: 0,\n            contains: [\n              ANNOTATION,\n              hljs.APOS_STRING_MODE,\n              hljs.QUOTE_STRING_MODE,\n              NUMBER,\n              hljs.C_BLOCK_COMMENT_MODE\n            ]\n          },\n          hljs.C_LINE_COMMENT_MODE,\n          hljs.C_BLOCK_COMMENT_MODE\n        ]\n      },\n      NUMBER,\n      ANNOTATION\n    ]\n  };\n}\n\nmodule.exports = java;\n","const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';\nconst KEYWORDS = [\n  \"as\", // for exports\n  \"in\",\n  \"of\",\n  \"if\",\n  \"for\",\n  \"while\",\n  \"finally\",\n  \"var\",\n  \"new\",\n  \"function\",\n  \"do\",\n  \"return\",\n  \"void\",\n  \"else\",\n  \"break\",\n  \"catch\",\n  \"instanceof\",\n  \"with\",\n  \"throw\",\n  \"case\",\n  \"default\",\n  \"try\",\n  \"switch\",\n  \"continue\",\n  \"typeof\",\n  \"delete\",\n  \"let\",\n  \"yield\",\n  \"const\",\n  \"class\",\n  // JS handles these with a special rule\n  // \"get\",\n  // \"set\",\n  \"debugger\",\n  \"async\",\n  \"await\",\n  \"static\",\n  \"import\",\n  \"from\",\n  \"export\",\n  \"extends\"\n];\nconst LITERALS = [\n  \"true\",\n  \"false\",\n  \"null\",\n  \"undefined\",\n  \"NaN\",\n  \"Infinity\"\n];\n\nconst TYPES = [\n  \"Intl\",\n  \"DataView\",\n  \"Number\",\n  \"Math\",\n  \"Date\",\n  \"String\",\n  \"RegExp\",\n  \"Object\",\n  \"Function\",\n  \"Boolean\",\n  \"Error\",\n  \"Symbol\",\n  \"Set\",\n  \"Map\",\n  \"WeakSet\",\n  \"WeakMap\",\n  \"Proxy\",\n  \"Reflect\",\n  \"JSON\",\n  \"Promise\",\n  \"Float64Array\",\n  \"Int16Array\",\n  \"Int32Array\",\n  \"Int8Array\",\n  \"Uint16Array\",\n  \"Uint32Array\",\n  \"Float32Array\",\n  \"Array\",\n  \"Uint8Array\",\n  \"Uint8ClampedArray\",\n  \"ArrayBuffer\",\n  \"BigInt64Array\",\n  \"BigUint64Array\",\n  \"BigInt\"\n];\n\nconst ERROR_TYPES = [\n  \"EvalError\",\n  \"InternalError\",\n  \"RangeError\",\n  \"ReferenceError\",\n  \"SyntaxError\",\n  \"TypeError\",\n  \"URIError\"\n];\n\nconst BUILT_IN_GLOBALS = [\n  \"setInterval\",\n  \"setTimeout\",\n  \"clearInterval\",\n  \"clearTimeout\",\n\n  \"require\",\n  \"exports\",\n\n  \"eval\",\n  \"isFinite\",\n  \"isNaN\",\n  \"parseFloat\",\n  \"parseInt\",\n  \"decodeURI\",\n  \"decodeURIComponent\",\n  \"encodeURI\",\n  \"encodeURIComponent\",\n  \"escape\",\n  \"unescape\"\n];\n\nconst BUILT_IN_VARIABLES = [\n  \"arguments\",\n  \"this\",\n  \"super\",\n  \"console\",\n  \"window\",\n  \"document\",\n  \"localStorage\",\n  \"module\",\n  \"global\" // Node.js\n];\n\nconst BUILT_INS = [].concat(\n  BUILT_IN_GLOBALS,\n  BUILT_IN_VARIABLES,\n  TYPES,\n  ERROR_TYPES\n);\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: JavaScript\nDescription: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.\nCategory: common, scripting\nWebsite: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n*/\n\n/** @type LanguageFn */\nfunction javascript(hljs) {\n  /**\n   * Takes a string like \" {\n    const tag = \"',\n    end: ''\n  };\n  const XML_TAG = {\n    begin: /<[A-Za-z0-9\\\\._:-]+/,\n    end: /\\/[A-Za-z0-9\\\\._:-]+>|\\/>/,\n    /**\n     * @param {RegExpMatchArray} match\n     * @param {CallbackResponse} response\n     */\n    isTrulyOpeningTag: (match, response) => {\n      const afterMatchIndex = match[0].length + match.index;\n      const nextChar = match.input[afterMatchIndex];\n      // nested type?\n      // HTML should not include another raw `<` inside a tag\n      // But a type might: `>`, etc.\n      if (nextChar === \"<\") {\n        response.ignoreMatch();\n        return;\n      }\n      // \n      // This is now either a tag or a type.\n      if (nextChar === \">\") {\n        // if we cannot find a matching closing tag, then we\n        // will ignore it\n        if (!hasClosingTag(match, { after: afterMatchIndex })) {\n          response.ignoreMatch();\n        }\n      }\n    }\n  };\n  const KEYWORDS$1 = {\n    $pattern: IDENT_RE,\n    keyword: KEYWORDS,\n    literal: LITERALS,\n    built_in: BUILT_INS\n  };\n\n  // https://tc39.es/ecma262/#sec-literals-numeric-literals\n  const decimalDigits = '[0-9](_?[0-9])*';\n  const frac = `\\\\.(${decimalDigits})`;\n  // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral\n  // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals\n  const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;\n  const NUMBER = {\n    className: 'number',\n    variants: [\n      // DecimalLiteral\n      { begin: `(\\\\b(${decimalInteger})((${frac})|\\\\.)?|(${frac}))` +\n        `[eE][+-]?(${decimalDigits})\\\\b` },\n      { begin: `\\\\b(${decimalInteger})\\\\b((${frac})\\\\b|\\\\.)?|(${frac})\\\\b` },\n\n      // DecimalBigIntegerLiteral\n      { begin: `\\\\b(0|[1-9](_?[0-9])*)n\\\\b` },\n\n      // NonDecimalIntegerLiteral\n      { begin: \"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\\\b\" },\n      { begin: \"\\\\b0[bB][0-1](_?[0-1])*n?\\\\b\" },\n      { begin: \"\\\\b0[oO][0-7](_?[0-7])*n?\\\\b\" },\n\n      // LegacyOctalIntegerLiteral (does not include underscore separators)\n      // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals\n      { begin: \"\\\\b0[0-7]+n?\\\\b\" },\n    ],\n    relevance: 0\n  };\n\n  const SUBST = {\n    className: 'subst',\n    begin: '\\\\$\\\\{',\n    end: '\\\\}',\n    keywords: KEYWORDS$1,\n    contains: [] // defined later\n  };\n  const HTML_TEMPLATE = {\n    begin: 'html`',\n    end: '',\n    starts: {\n      end: '`',\n      returnEnd: false,\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        SUBST\n      ],\n      subLanguage: 'xml'\n    }\n  };\n  const CSS_TEMPLATE = {\n    begin: 'css`',\n    end: '',\n    starts: {\n      end: '`',\n      returnEnd: false,\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        SUBST\n      ],\n      subLanguage: 'css'\n    }\n  };\n  const TEMPLATE_STRING = {\n    className: 'string',\n    begin: '`',\n    end: '`',\n    contains: [\n      hljs.BACKSLASH_ESCAPE,\n      SUBST\n    ]\n  };\n  const JSDOC_COMMENT = hljs.COMMENT(\n    /\\/\\*\\*(?!\\/)/,\n    '\\\\*/',\n    {\n      relevance: 0,\n      contains: [\n        {\n          className: 'doctag',\n          begin: '@[A-Za-z]+',\n          contains: [\n            {\n              className: 'type',\n              begin: '\\\\{',\n              end: '\\\\}',\n              relevance: 0\n            },\n            {\n              className: 'variable',\n              begin: IDENT_RE$1 + '(?=\\\\s*(-)|$)',\n              endsParent: true,\n              relevance: 0\n            },\n            // eat spaces (not newlines) so we can find\n            // types or variables\n            {\n              begin: /(?=[^\\n])\\s/,\n              relevance: 0\n            }\n          ]\n        }\n      ]\n    }\n  );\n  const COMMENT = {\n    className: \"comment\",\n    variants: [\n      JSDOC_COMMENT,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.C_LINE_COMMENT_MODE\n    ]\n  };\n  const SUBST_INTERNALS = [\n    hljs.APOS_STRING_MODE,\n    hljs.QUOTE_STRING_MODE,\n    HTML_TEMPLATE,\n    CSS_TEMPLATE,\n    TEMPLATE_STRING,\n    NUMBER,\n    hljs.REGEXP_MODE\n  ];\n  SUBST.contains = SUBST_INTERNALS\n    .concat({\n      // we need to pair up {} inside our subst to prevent\n      // it from ending too early by matching another }\n      begin: /\\{/,\n      end: /\\}/,\n      keywords: KEYWORDS$1,\n      contains: [\n        \"self\"\n      ].concat(SUBST_INTERNALS)\n    });\n  const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);\n  const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([\n    // eat recursive parens in sub expressions\n    {\n      begin: /\\(/,\n      end: /\\)/,\n      keywords: KEYWORDS$1,\n      contains: [\"self\"].concat(SUBST_AND_COMMENTS)\n    }\n  ]);\n  const PARAMS = {\n    className: 'params',\n    begin: /\\(/,\n    end: /\\)/,\n    excludeBegin: true,\n    excludeEnd: true,\n    keywords: KEYWORDS$1,\n    contains: PARAMS_CONTAINS\n  };\n\n  return {\n    name: 'Javascript',\n    aliases: ['js', 'jsx', 'mjs', 'cjs'],\n    keywords: KEYWORDS$1,\n    // this will be extended by TypeScript\n    exports: { PARAMS_CONTAINS },\n    illegal: /#(?![$_A-z])/,\n    contains: [\n      hljs.SHEBANG({\n        label: \"shebang\",\n        binary: \"node\",\n        relevance: 5\n      }),\n      {\n        label: \"use_strict\",\n        className: 'meta',\n        relevance: 10,\n        begin: /^\\s*['\"]use (strict|asm)['\"]/\n      },\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      HTML_TEMPLATE,\n      CSS_TEMPLATE,\n      TEMPLATE_STRING,\n      COMMENT,\n      NUMBER,\n      { // object attr container\n        begin: concat(/[{,\\n]\\s*/,\n          // we need to look ahead to make sure that we actually have an\n          // attribute coming up so we don't steal a comma from a potential\n          // \"value\" container\n          //\n          // NOTE: this might not work how you think.  We don't actually always\n          // enter this mode and stay.  Instead it might merely match `,\n          // ` and then immediately end after the , because it\n          // fails to find any actual attrs. But this still does the job because\n          // it prevents the value contain rule from grabbing this instead and\n          // prevening this rule from firing when we actually DO have keys.\n          lookahead(concat(\n            // we also need to allow for multiple possible comments inbetween\n            // the first key:value pairing\n            /(((\\/\\/.*$)|(\\/\\*(\\*[^/]|[^*])*\\*\\/))\\s*)*/,\n            IDENT_RE$1 + '\\\\s*:'))),\n        relevance: 0,\n        contains: [\n          {\n            className: 'attr',\n            begin: IDENT_RE$1 + lookahead('\\\\s*:'),\n            relevance: 0\n          }\n        ]\n      },\n      { // \"value\" container\n        begin: '(' + hljs.RE_STARTERS_RE + '|\\\\b(case|return|throw)\\\\b)\\\\s*',\n        keywords: 'return throw case',\n        contains: [\n          COMMENT,\n          hljs.REGEXP_MODE,\n          {\n            className: 'function',\n            // we have to count the parens to make sure we actually have the\n            // correct bounding ( ) before the =>.  There could be any number of\n            // sub-expressions inside also surrounded by parens.\n            begin: '(\\\\(' +\n            '[^()]*(\\\\(' +\n            '[^()]*(\\\\(' +\n            '[^()]*' +\n            '\\\\)[^()]*)*' +\n            '\\\\)[^()]*)*' +\n            '\\\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\\\s*=>',\n            returnBegin: true,\n            end: '\\\\s*=>',\n            contains: [\n              {\n                className: 'params',\n                variants: [\n                  {\n                    begin: hljs.UNDERSCORE_IDENT_RE,\n                    relevance: 0\n                  },\n                  {\n                    className: null,\n                    begin: /\\(\\s*\\)/,\n                    skip: true\n                  },\n                  {\n                    begin: /\\(/,\n                    end: /\\)/,\n                    excludeBegin: true,\n                    excludeEnd: true,\n                    keywords: KEYWORDS$1,\n                    contains: PARAMS_CONTAINS\n                  }\n                ]\n              }\n            ]\n          },\n          { // could be a comma delimited list of params to a function call\n            begin: /,/, relevance: 0\n          },\n          {\n            className: '',\n            begin: /\\s/,\n            end: /\\s*/,\n            skip: true\n          },\n          { // JSX\n            variants: [\n              { begin: FRAGMENT.begin, end: FRAGMENT.end },\n              {\n                begin: XML_TAG.begin,\n                // we carefully check the opening tag to see if it truly\n                // is a tag and not a false positive\n                'on:begin': XML_TAG.isTrulyOpeningTag,\n                end: XML_TAG.end\n              }\n            ],\n            subLanguage: 'xml',\n            contains: [\n              {\n                begin: XML_TAG.begin,\n                end: XML_TAG.end,\n                skip: true,\n                contains: ['self']\n              }\n            ]\n          }\n        ],\n        relevance: 0\n      },\n      {\n        className: 'function',\n        beginKeywords: 'function',\n        end: /[{;]/,\n        excludeEnd: true,\n        keywords: KEYWORDS$1,\n        contains: [\n          'self',\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n          PARAMS\n        ],\n        illegal: /%/\n      },\n      {\n        // prevent this from getting swallowed up by function\n        // since they appear \"function like\"\n        beginKeywords: \"while if switch catch for\"\n      },\n      {\n        className: 'function',\n        // we have to count the parens to make sure we actually have the correct\n        // bounding ( ).  There could be any number of sub-expressions inside\n        // also surrounded by parens.\n        begin: hljs.UNDERSCORE_IDENT_RE +\n          '\\\\(' + // first parens\n          '[^()]*(\\\\(' +\n            '[^()]*(\\\\(' +\n              '[^()]*' +\n            '\\\\)[^()]*)*' +\n          '\\\\)[^()]*)*' +\n          '\\\\)\\\\s*\\\\{', // end parens\n        returnBegin:true,\n        contains: [\n          PARAMS,\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n        ]\n      },\n      // hack: prevents detection of keywords in some circumstances\n      // .keyword()\n      // $keyword = x\n      {\n        variants: [\n          { begin: '\\\\.' + IDENT_RE$1 },\n          { begin: '\\\\$' + IDENT_RE$1 }\n        ],\n        relevance: 0\n      },\n      { // ES6 class\n        className: 'class',\n        beginKeywords: 'class',\n        end: /[{;=]/,\n        excludeEnd: true,\n        illegal: /[:\"[\\]]/,\n        contains: [\n          { beginKeywords: 'extends' },\n          hljs.UNDERSCORE_TITLE_MODE\n        ]\n      },\n      {\n        begin: /\\b(?=constructor)/,\n        end: /[{;]/,\n        excludeEnd: true,\n        contains: [\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n          'self',\n          PARAMS\n        ]\n      },\n      {\n        begin: '(get|set)\\\\s+(?=' + IDENT_RE$1 + '\\\\()',\n        end: /\\{/,\n        keywords: \"get set\",\n        contains: [\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n          { begin: /\\(\\)/ }, // eat to avoid empty params\n          PARAMS\n        ]\n      },\n      {\n        begin: /\\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`\n      }\n    ]\n  };\n}\n\nmodule.exports = javascript;\n","/*\nLanguage: JSON\nDescription: JSON (JavaScript Object Notation) is a lightweight data-interchange format.\nAuthor: Ivan Sagalaev \nWebsite: http://www.json.org\nCategory: common, protocols\n*/\n\nfunction json(hljs) {\n  const LITERALS = {\n    literal: 'true false null'\n  };\n  const ALLOWED_COMMENTS = [\n    hljs.C_LINE_COMMENT_MODE,\n    hljs.C_BLOCK_COMMENT_MODE\n  ];\n  const TYPES = [\n    hljs.QUOTE_STRING_MODE,\n    hljs.C_NUMBER_MODE\n  ];\n  const VALUE_CONTAINER = {\n    end: ',',\n    endsWithParent: true,\n    excludeEnd: true,\n    contains: TYPES,\n    keywords: LITERALS\n  };\n  const OBJECT = {\n    begin: /\\{/,\n    end: /\\}/,\n    contains: [\n      {\n        className: 'attr',\n        begin: /\"/,\n        end: /\"/,\n        contains: [hljs.BACKSLASH_ESCAPE],\n        illegal: '\\\\n'\n      },\n      hljs.inherit(VALUE_CONTAINER, {\n        begin: /:/\n      })\n    ].concat(ALLOWED_COMMENTS),\n    illegal: '\\\\S'\n  };\n  const ARRAY = {\n    begin: '\\\\[',\n    end: '\\\\]',\n    contains: [hljs.inherit(VALUE_CONTAINER)], // inherit is a workaround for a bug that makes shared modes with endsWithParent compile only the ending of one of the parents\n    illegal: '\\\\S'\n  };\n  TYPES.push(OBJECT, ARRAY);\n  ALLOWED_COMMENTS.forEach(function(rule) {\n    TYPES.push(rule);\n  });\n  return {\n    name: 'JSON',\n    contains: TYPES,\n    keywords: LITERALS,\n    illegal: '\\\\S'\n  };\n}\n\nmodule.exports = json;\n","// https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10\nvar decimalDigits = '[0-9](_*[0-9])*';\nvar frac = `\\\\.(${decimalDigits})`;\nvar hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';\nvar NUMERIC = {\n  className: 'number',\n  variants: [\n    // DecimalFloatingPointLiteral\n    // including ExponentPart\n    { begin: `(\\\\b(${decimalDigits})((${frac})|\\\\.)?|(${frac}))` +\n      `[eE][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n    // excluding ExponentPart\n    { begin: `\\\\b(${decimalDigits})((${frac})[fFdD]?\\\\b|\\\\.([fFdD]\\\\b)?)` },\n    { begin: `(${frac})[fFdD]?\\\\b` },\n    { begin: `\\\\b(${decimalDigits})[fFdD]\\\\b` },\n\n    // HexadecimalFloatingPointLiteral\n    { begin: `\\\\b0[xX]((${hexDigits})\\\\.?|(${hexDigits})?\\\\.(${hexDigits}))` +\n      `[pP][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n\n    // DecimalIntegerLiteral\n    { begin: '\\\\b(0|[1-9](_*[0-9])*)[lL]?\\\\b' },\n\n    // HexIntegerLiteral\n    { begin: `\\\\b0[xX](${hexDigits})[lL]?\\\\b` },\n\n    // OctalIntegerLiteral\n    { begin: '\\\\b0(_*[0-7])*[lL]?\\\\b' },\n\n    // BinaryIntegerLiteral\n    { begin: '\\\\b0[bB][01](_*[01])*[lL]?\\\\b' },\n  ],\n  relevance: 0\n};\n\n/*\n Language: Kotlin\n Description: Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native.\n Author: Sergey Mashkov \n Website: https://kotlinlang.org\n Category: common\n */\n\nfunction kotlin(hljs) {\n  const KEYWORDS = {\n    keyword:\n      'abstract as val var vararg get set class object open private protected public noinline ' +\n      'crossinline dynamic final enum if else do while for when throw try catch finally ' +\n      'import package is in fun override companion reified inline lateinit init ' +\n      'interface annotation data sealed internal infix operator out by constructor super ' +\n      'tailrec where const inner suspend typealias external expect actual',\n    built_in:\n      'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',\n    literal:\n      'true false null'\n  };\n  const KEYWORDS_WITH_LABEL = {\n    className: 'keyword',\n    begin: /\\b(break|continue|return|this)\\b/,\n    starts: {\n      contains: [\n        {\n          className: 'symbol',\n          begin: /@\\w+/\n        }\n      ]\n    }\n  };\n  const LABEL = {\n    className: 'symbol',\n    begin: hljs.UNDERSCORE_IDENT_RE + '@'\n  };\n\n  // for string templates\n  const SUBST = {\n    className: 'subst',\n    begin: /\\$\\{/,\n    end: /\\}/,\n    contains: [ hljs.C_NUMBER_MODE ]\n  };\n  const VARIABLE = {\n    className: 'variable',\n    begin: '\\\\$' + hljs.UNDERSCORE_IDENT_RE\n  };\n  const STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: '\"\"\"',\n        end: '\"\"\"(?=[^\"])',\n        contains: [\n          VARIABLE,\n          SUBST\n        ]\n      },\n      // Can't use built-in modes easily, as we want to use STRING in the meta\n      // context as 'meta-string' and there's no syntax to remove explicitly set\n      // classNames in built-in modes.\n      {\n        begin: '\\'',\n        end: '\\'',\n        illegal: /\\n/,\n        contains: [ hljs.BACKSLASH_ESCAPE ]\n      },\n      {\n        begin: '\"',\n        end: '\"',\n        illegal: /\\n/,\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          VARIABLE,\n          SUBST\n        ]\n      }\n    ]\n  };\n  SUBST.contains.push(STRING);\n\n  const ANNOTATION_USE_SITE = {\n    className: 'meta',\n    begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\\\s*:(?:\\\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'\n  };\n  const ANNOTATION = {\n    className: 'meta',\n    begin: '@' + hljs.UNDERSCORE_IDENT_RE,\n    contains: [\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [\n          hljs.inherit(STRING, {\n            className: 'meta-string'\n          })\n        ]\n      }\n    ]\n  };\n\n  // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals\n  // According to the doc above, the number mode of kotlin is the same as java 8,\n  // so the code below is copied from java.js\n  const KOTLIN_NUMBER_MODE = NUMERIC;\n  const KOTLIN_NESTED_COMMENT = hljs.COMMENT(\n    '/\\\\*', '\\\\*/',\n    {\n      contains: [ hljs.C_BLOCK_COMMENT_MODE ]\n    }\n  );\n  const KOTLIN_PAREN_TYPE = {\n    variants: [\n      {\n        className: 'type',\n        begin: hljs.UNDERSCORE_IDENT_RE\n      },\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [] // defined later\n      }\n    ]\n  };\n  const KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE;\n  KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ];\n  KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ];\n\n  return {\n    name: 'Kotlin',\n    aliases: [ 'kt', 'kts' ],\n    keywords: KEYWORDS,\n    contains: [\n      hljs.COMMENT(\n        '/\\\\*\\\\*',\n        '\\\\*/',\n        {\n          relevance: 0,\n          contains: [\n            {\n              className: 'doctag',\n              begin: '@[A-Za-z]+'\n            }\n          ]\n        }\n      ),\n      hljs.C_LINE_COMMENT_MODE,\n      KOTLIN_NESTED_COMMENT,\n      KEYWORDS_WITH_LABEL,\n      LABEL,\n      ANNOTATION_USE_SITE,\n      ANNOTATION,\n      {\n        className: 'function',\n        beginKeywords: 'fun',\n        end: '[(]|$',\n        returnBegin: true,\n        excludeEnd: true,\n        keywords: KEYWORDS,\n        relevance: 5,\n        contains: [\n          {\n            begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n            returnBegin: true,\n            relevance: 0,\n            contains: [ hljs.UNDERSCORE_TITLE_MODE ]\n          },\n          {\n            className: 'type',\n            begin: //,\n            keywords: 'reified',\n            relevance: 0\n          },\n          {\n            className: 'params',\n            begin: /\\(/,\n            end: /\\)/,\n            endsParent: true,\n            keywords: KEYWORDS,\n            relevance: 0,\n            contains: [\n              {\n                begin: /:/,\n                end: /[=,\\/]/,\n                endsWithParent: true,\n                contains: [\n                  KOTLIN_PAREN_TYPE,\n                  hljs.C_LINE_COMMENT_MODE,\n                  KOTLIN_NESTED_COMMENT\n                ],\n                relevance: 0\n              },\n              hljs.C_LINE_COMMENT_MODE,\n              KOTLIN_NESTED_COMMENT,\n              ANNOTATION_USE_SITE,\n              ANNOTATION,\n              STRING,\n              hljs.C_NUMBER_MODE\n            ]\n          },\n          KOTLIN_NESTED_COMMENT\n        ]\n      },\n      {\n        className: 'class',\n        beginKeywords: 'class interface trait', // remove 'trait' when removed from KEYWORDS\n        end: /[:\\{(]|$/,\n        excludeEnd: true,\n        illegal: 'extends implements',\n        contains: [\n          {\n            beginKeywords: 'public protected internal private constructor'\n          },\n          hljs.UNDERSCORE_TITLE_MODE,\n          {\n            className: 'type',\n            begin: //,\n            excludeBegin: true,\n            excludeEnd: true,\n            relevance: 0\n          },\n          {\n            className: 'type',\n            begin: /[,:]\\s*/,\n            end: /[<\\(,]|$/,\n            excludeBegin: true,\n            returnEnd: true\n          },\n          ANNOTATION_USE_SITE,\n          ANNOTATION\n        ]\n      },\n      STRING,\n      {\n        className: 'meta',\n        begin: \"^#!/usr/bin/env\",\n        end: '$',\n        illegal: '\\n'\n      },\n      KOTLIN_NUMBER_MODE\n    ]\n  };\n}\n\nmodule.exports = kotlin;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: Markdown\nRequires: xml.js\nAuthor: John Crepezzi \nWebsite: https://daringfireball.net/projects/markdown/\nCategory: common, markup\n*/\n\nfunction markdown(hljs) {\n  const INLINE_HTML = {\n    begin: /<\\/?[A-Za-z_]/,\n    end: '>',\n    subLanguage: 'xml',\n    relevance: 0\n  };\n  const HORIZONTAL_RULE = {\n    begin: '^[-\\\\*]{3,}',\n    end: '$'\n  };\n  const CODE = {\n    className: 'code',\n    variants: [\n      // TODO: fix to allow these to work with sublanguage also\n      {\n        begin: '(`{3,})[^`](.|\\\\n)*?\\\\1`*[ ]*'\n      },\n      {\n        begin: '(~{3,})[^~](.|\\\\n)*?\\\\1~*[ ]*'\n      },\n      // needed to allow markdown as a sublanguage to work\n      {\n        begin: '```',\n        end: '```+[ ]*$'\n      },\n      {\n        begin: '~~~',\n        end: '~~~+[ ]*$'\n      },\n      {\n        begin: '`.+?`'\n      },\n      {\n        begin: '(?=^( {4}|\\\\t))',\n        // use contains to gobble up multiple lines to allow the block to be whatever size\n        // but only have a single open/close tag vs one per line\n        contains: [\n          {\n            begin: '^( {4}|\\\\t)',\n            end: '(\\\\n)$'\n          }\n        ],\n        relevance: 0\n      }\n    ]\n  };\n  const LIST = {\n    className: 'bullet',\n    begin: '^[ \\t]*([*+-]|(\\\\d+\\\\.))(?=\\\\s+)',\n    end: '\\\\s+',\n    excludeEnd: true\n  };\n  const LINK_REFERENCE = {\n    begin: /^\\[[^\\n]+\\]:/,\n    returnBegin: true,\n    contains: [\n      {\n        className: 'symbol',\n        begin: /\\[/,\n        end: /\\]/,\n        excludeBegin: true,\n        excludeEnd: true\n      },\n      {\n        className: 'link',\n        begin: /:\\s*/,\n        end: /$/,\n        excludeBegin: true\n      }\n    ]\n  };\n  const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;\n  const LINK = {\n    variants: [\n      // too much like nested array access in so many languages\n      // to have any real relevance\n      {\n        begin: /\\[.+?\\]\\[.*?\\]/,\n        relevance: 0\n      },\n      // popular internet URLs\n      {\n        begin: /\\[.+?\\]\\(((data|javascript|mailto):|(?:http|ftp)s?:\\/\\/).*?\\)/,\n        relevance: 2\n      },\n      {\n        begin: concat(/\\[.+?\\]\\(/, URL_SCHEME, /:\\/\\/.*?\\)/),\n        relevance: 2\n      },\n      // relative urls\n      {\n        begin: /\\[.+?\\]\\([./?&#].*?\\)/,\n        relevance: 1\n      },\n      // whatever else, lower relevance (might not be a link at all)\n      {\n        begin: /\\[.+?\\]\\(.*?\\)/,\n        relevance: 0\n      }\n    ],\n    returnBegin: true,\n    contains: [\n      {\n        className: 'string',\n        relevance: 0,\n        begin: '\\\\[',\n        end: '\\\\]',\n        excludeBegin: true,\n        returnEnd: true\n      },\n      {\n        className: 'link',\n        relevance: 0,\n        begin: '\\\\]\\\\(',\n        end: '\\\\)',\n        excludeBegin: true,\n        excludeEnd: true\n      },\n      {\n        className: 'symbol',\n        relevance: 0,\n        begin: '\\\\]\\\\[',\n        end: '\\\\]',\n        excludeBegin: true,\n        excludeEnd: true\n      }\n    ]\n  };\n  const BOLD = {\n    className: 'strong',\n    contains: [], // defined later\n    variants: [\n      {\n        begin: /_{2}/,\n        end: /_{2}/\n      },\n      {\n        begin: /\\*{2}/,\n        end: /\\*{2}/\n      }\n    ]\n  };\n  const ITALIC = {\n    className: 'emphasis',\n    contains: [], // defined later\n    variants: [\n      {\n        begin: /\\*(?!\\*)/,\n        end: /\\*/\n      },\n      {\n        begin: /_(?!_)/,\n        end: /_/,\n        relevance: 0\n      }\n    ]\n  };\n  BOLD.contains.push(ITALIC);\n  ITALIC.contains.push(BOLD);\n\n  let CONTAINABLE = [\n    INLINE_HTML,\n    LINK\n  ];\n\n  BOLD.contains = BOLD.contains.concat(CONTAINABLE);\n  ITALIC.contains = ITALIC.contains.concat(CONTAINABLE);\n\n  CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);\n\n  const HEADER = {\n    className: 'section',\n    variants: [\n      {\n        begin: '^#{1,6}',\n        end: '$',\n        contains: CONTAINABLE\n      },\n      {\n        begin: '(?=^.+?\\\\n[=-]{2,}$)',\n        contains: [\n          {\n            begin: '^[=-]*$'\n          },\n          {\n            begin: '^',\n            end: \"\\\\n\",\n            contains: CONTAINABLE\n          }\n        ]\n      }\n    ]\n  };\n\n  const BLOCKQUOTE = {\n    className: 'quote',\n    begin: '^>\\\\s+',\n    contains: CONTAINABLE,\n    end: '$'\n  };\n\n  return {\n    name: 'Markdown',\n    aliases: [\n      'md',\n      'mkdown',\n      'mkd'\n    ],\n    contains: [\n      HEADER,\n      INLINE_HTML,\n      LIST,\n      BOLD,\n      ITALIC,\n      BLOCKQUOTE,\n      CODE,\n      HORIZONTAL_RULE,\n      LINK,\n      LINK_REFERENCE\n    ]\n  };\n}\n\nmodule.exports = markdown;\n","/*\nLanguage: Nix\nAuthor: Domen Kožar \nDescription: Nix functional language\nWebsite: http://nixos.org/nix\n*/\n\nfunction nix(hljs) {\n  const NIX_KEYWORDS = {\n    keyword:\n      'rec with let in inherit assert if else then',\n    literal:\n      'true false or and null',\n    built_in:\n      'import abort baseNameOf dirOf isNull builtins map removeAttrs throw ' +\n      'toString derivation'\n  };\n  const ANTIQUOTE = {\n    className: 'subst',\n    begin: /\\$\\{/,\n    end: /\\}/,\n    keywords: NIX_KEYWORDS\n  };\n  const ATTRS = {\n    begin: /[a-zA-Z0-9-_]+(\\s*=)/,\n    returnBegin: true,\n    relevance: 0,\n    contains: [\n      {\n        className: 'attr',\n        begin: /\\S+/\n      }\n    ]\n  };\n  const STRING = {\n    className: 'string',\n    contains: [ ANTIQUOTE ],\n    variants: [\n      {\n        begin: \"''\",\n        end: \"''\"\n      },\n      {\n        begin: '\"',\n        end: '\"'\n      }\n    ]\n  };\n  const EXPRESSIONS = [\n    hljs.NUMBER_MODE,\n    hljs.HASH_COMMENT_MODE,\n    hljs.C_BLOCK_COMMENT_MODE,\n    STRING,\n    ATTRS\n  ];\n  ANTIQUOTE.contains = EXPRESSIONS;\n  return {\n    name: 'Nix',\n    aliases: [ \"nixos\" ],\n    keywords: NIX_KEYWORDS,\n    contains: EXPRESSIONS\n  };\n}\n\nmodule.exports = nix;\n","/*\nLanguage: PowerShell\nDescription: PowerShell is a task-based command-line shell and scripting language built on .NET.\nAuthor: David Mohundro \nContributors: Nicholas Blumhardt , Victor Zhou , Nicolas Le Gall \nWebsite: https://docs.microsoft.com/en-us/powershell/\n*/\n\nfunction powershell(hljs) {\n  const TYPES = [\n    \"string\",\n    \"char\",\n    \"byte\",\n    \"int\",\n    \"long\",\n    \"bool\",\n    \"decimal\",\n    \"single\",\n    \"double\",\n    \"DateTime\",\n    \"xml\",\n    \"array\",\n    \"hashtable\",\n    \"void\"\n  ];\n\n  // https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands\n  const VALID_VERBS =\n    'Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|' +\n    'Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|' +\n    'Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|' +\n    'Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|' +\n    'ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|' +\n    'Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|' +\n    'Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|' +\n    'Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|' +\n    'Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|' +\n    'Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|' +\n    'Unprotect|Use|ForEach|Sort|Tee|Where';\n\n  const COMPARISON_OPERATORS =\n    '-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|' +\n    '-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|' +\n    '-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|' +\n    '-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|' +\n    '-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|' +\n    '-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|' +\n    '-split|-wildcard|-xor';\n\n  const KEYWORDS = {\n    $pattern: /-?[A-z\\.\\-]+\\b/,\n    keyword:\n      'if else foreach return do while until elseif begin for trap data dynamicparam ' +\n      'end break throw param continue finally in switch exit filter try process catch ' +\n      'hidden static parameter',\n    // \"echo\" relevance has been set to 0 to avoid auto-detect conflicts with shell transcripts\n    built_in:\n      'ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp ' +\n      'cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx ' +\n      'fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group ' +\n      'gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi ' +\n      'iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh ' +\n      'popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp ' +\n      'rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp ' +\n      'spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write'\n    // TODO: 'validate[A-Z]+' can't work in keywords\n  };\n\n  const TITLE_NAME_RE = /\\w[\\w\\d]*((-)[\\w\\d]+)*/;\n\n  const BACKTICK_ESCAPE = {\n    begin: '`[\\\\s\\\\S]',\n    relevance: 0\n  };\n\n  const VAR = {\n    className: 'variable',\n    variants: [\n      {\n        begin: /\\$\\B/\n      },\n      {\n        className: 'keyword',\n        begin: /\\$this/\n      },\n      {\n        begin: /\\$[\\w\\d][\\w\\d_:]*/\n      }\n    ]\n  };\n\n  const LITERAL = {\n    className: 'literal',\n    begin: /\\$(null|true|false)\\b/\n  };\n\n  const QUOTE_STRING = {\n    className: \"string\",\n    variants: [\n      {\n        begin: /\"/,\n        end: /\"/\n      },\n      {\n        begin: /@\"/,\n        end: /^\"@/\n      }\n    ],\n    contains: [\n      BACKTICK_ESCAPE,\n      VAR,\n      {\n        className: 'variable',\n        begin: /\\$[A-z]/,\n        end: /[^A-z]/\n      }\n    ]\n  };\n\n  const APOS_STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: /'/,\n        end: /'/\n      },\n      {\n        begin: /@'/,\n        end: /^'@/\n      }\n    ]\n  };\n\n  const PS_HELPTAGS = {\n    className: \"doctag\",\n    variants: [\n      /* no paramater help tags */\n      {\n        begin: /\\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/\n      },\n      /* one parameter help tags */\n      {\n        begin: /\\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\\s+\\S+/\n      }\n    ]\n  };\n\n  const PS_COMMENT = hljs.inherit(\n    hljs.COMMENT(null, null),\n    {\n      variants: [\n        /* single-line comment */\n        {\n          begin: /#/,\n          end: /$/\n        },\n        /* multi-line comment */\n        {\n          begin: /<#/,\n          end: /#>/\n        }\n      ],\n      contains: [ PS_HELPTAGS ]\n    }\n  );\n\n  const CMDLETS = {\n    className: 'built_in',\n    variants: [\n      {\n        begin: '('.concat(VALID_VERBS, ')+(-)[\\\\w\\\\d]+')\n      }\n    ]\n  };\n\n  const PS_CLASS = {\n    className: 'class',\n    beginKeywords: 'class enum',\n    end: /\\s*[{]/,\n    excludeEnd: true,\n    relevance: 0,\n    contains: [ hljs.TITLE_MODE ]\n  };\n\n  const PS_FUNCTION = {\n    className: 'function',\n    begin: /function\\s+/,\n    end: /\\s*\\{|$/,\n    excludeEnd: true,\n    returnBegin: true,\n    relevance: 0,\n    contains: [\n      {\n        begin: \"function\",\n        relevance: 0,\n        className: \"keyword\"\n      },\n      {\n        className: \"title\",\n        begin: TITLE_NAME_RE,\n        relevance: 0\n      },\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        className: \"params\",\n        relevance: 0,\n        contains: [ VAR ]\n      }\n      // CMDLETS\n    ]\n  };\n\n  // Using statment, plus type, plus assembly name.\n  const PS_USING = {\n    begin: /using\\s/,\n    end: /$/,\n    returnBegin: true,\n    contains: [\n      QUOTE_STRING,\n      APOS_STRING,\n      {\n        className: 'keyword',\n        begin: /(using|assembly|command|module|namespace|type)/\n      }\n    ]\n  };\n\n  // Comperison operators & function named parameters.\n  const PS_ARGUMENTS = {\n    variants: [\n      // PS literals are pretty verbose so it's a good idea to accent them a bit.\n      {\n        className: 'operator',\n        begin: '('.concat(COMPARISON_OPERATORS, ')\\\\b')\n      },\n      {\n        className: 'literal',\n        begin: /(-)[\\w\\d]+/,\n        relevance: 0\n      }\n    ]\n  };\n\n  const HASH_SIGNS = {\n    className: 'selector-tag',\n    begin: /@\\B/,\n    relevance: 0\n  };\n\n  // It's a very general rule so I'll narrow it a bit with some strict boundaries\n  // to avoid any possible false-positive collisions!\n  const PS_METHODS = {\n    className: 'function',\n    begin: /\\[.*\\]\\s*[\\w]+[ ]??\\(/,\n    end: /$/,\n    returnBegin: true,\n    relevance: 0,\n    contains: [\n      {\n        className: 'keyword',\n        begin: '('.concat(\n          KEYWORDS.keyword.toString().replace(/\\s/g, '|'\n          ), ')\\\\b'),\n        endsParent: true,\n        relevance: 0\n      },\n      hljs.inherit(hljs.TITLE_MODE, {\n        endsParent: true\n      })\n    ]\n  };\n\n  const GENTLEMANS_SET = [\n    // STATIC_MEMBER,\n    PS_METHODS,\n    PS_COMMENT,\n    BACKTICK_ESCAPE,\n    hljs.NUMBER_MODE,\n    QUOTE_STRING,\n    APOS_STRING,\n    // PS_NEW_OBJECT_TYPE,\n    CMDLETS,\n    VAR,\n    LITERAL,\n    HASH_SIGNS\n  ];\n\n  const PS_TYPE = {\n    begin: /\\[/,\n    end: /\\]/,\n    excludeBegin: true,\n    excludeEnd: true,\n    relevance: 0,\n    contains: [].concat(\n      'self',\n      GENTLEMANS_SET,\n      {\n        begin: \"(\" + TYPES.join(\"|\") + \")\",\n        className: \"built_in\",\n        relevance: 0\n      },\n      {\n        className: 'type',\n        begin: /[\\.\\w\\d]+/,\n        relevance: 0\n      }\n    )\n  };\n\n  PS_METHODS.contains.unshift(PS_TYPE);\n\n  return {\n    name: 'PowerShell',\n    aliases: [\n      \"ps\",\n      \"ps1\"\n    ],\n    case_insensitive: true,\n    keywords: KEYWORDS,\n    contains: GENTLEMANS_SET.concat(\n      PS_CLASS,\n      PS_FUNCTION,\n      PS_USING,\n      PS_ARGUMENTS,\n      PS_TYPE\n    )\n  };\n}\n\nmodule.exports = powershell;\n","/*\nLanguage: .properties\nContributors: Valentin Aitken , Egor Rogov \nWebsite: https://en.wikipedia.org/wiki/.properties\nCategory: common, config\n*/\n\nfunction properties(hljs) {\n\n  // whitespaces: space, tab, formfeed\n  var WS0 = '[ \\\\t\\\\f]*';\n  var WS1 = '[ \\\\t\\\\f]+';\n  // delimiter\n  var EQUAL_DELIM = WS0+'[:=]'+WS0;\n  var WS_DELIM = WS1;\n  var DELIM = '(' + EQUAL_DELIM + '|' + WS_DELIM + ')';\n  var KEY_ALPHANUM = '([^\\\\\\\\\\\\W:= \\\\t\\\\f\\\\n]|\\\\\\\\.)+';\n  var KEY_OTHER = '([^\\\\\\\\:= \\\\t\\\\f\\\\n]|\\\\\\\\.)+';\n\n  var DELIM_AND_VALUE = {\n          // skip DELIM\n          end: DELIM,\n          relevance: 0,\n          starts: {\n            // value: everything until end of line (again, taking into account backslashes)\n            className: 'string',\n            end: /$/,\n            relevance: 0,\n            contains: [\n              { begin: '\\\\\\\\\\\\\\\\'},\n              { begin: '\\\\\\\\\\\\n' }\n            ]\n          }\n        };\n\n  return {\n    name: '.properties',\n    case_insensitive: true,\n    illegal: /\\S/,\n    contains: [\n      hljs.COMMENT('^\\\\s*[!#]', '$'),\n      // key: everything until whitespace or = or : (taking into account backslashes)\n      // case of a \"normal\" key\n      {\n        returnBegin: true,\n        variants: [\n          { begin: KEY_ALPHANUM + EQUAL_DELIM, relevance: 1 },\n          { begin: KEY_ALPHANUM + WS_DELIM, relevance: 0 }\n        ],\n        contains: [\n          {\n            className: 'attr',\n            begin: KEY_ALPHANUM,\n            endsParent: true,\n            relevance: 0\n          }\n        ],\n        starts: DELIM_AND_VALUE\n      },\n      // case of key containing non-alphanumeric chars => relevance = 0\n      {\n        begin: KEY_OTHER + DELIM,\n        returnBegin: true,\n        relevance: 0,\n        contains: [\n          {\n            className: 'meta',\n            begin: KEY_OTHER,\n            endsParent: true,\n            relevance: 0\n          }\n        ],\n        starts: DELIM_AND_VALUE\n      },\n      // case of an empty key\n      {\n        className: 'attr',\n        relevance: 0,\n        begin: KEY_OTHER + WS0 + '$'\n      }\n    ]\n  };\n}\n\nmodule.exports = properties;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: Ruby\nDescription: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.\nWebsite: https://www.ruby-lang.org/\nAuthor: Anton Kovalyov \nContributors: Peter Leonov , Vasily Polovnyov , Loren Segal , Pascal Hurni , Cedric Sohrauer \nCategory: common\n*/\n\nfunction ruby(hljs) {\n  const RUBY_METHOD_RE = '([a-zA-Z_]\\\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?)';\n  const RUBY_KEYWORDS = {\n    keyword:\n      'and then defined module in return redo if BEGIN retry end for self when ' +\n      'next until do begin unless END rescue else break undef not super class case ' +\n      'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor ' +\n      '__FILE__',\n    built_in: 'proc lambda',\n    literal:\n      'true false nil'\n  };\n  const YARDOCTAG = {\n    className: 'doctag',\n    begin: '@[A-Za-z]+'\n  };\n  const IRB_OBJECT = {\n    begin: '#<',\n    end: '>'\n  };\n  const COMMENT_MODES = [\n    hljs.COMMENT(\n      '#',\n      '$',\n      {\n        contains: [ YARDOCTAG ]\n      }\n    ),\n    hljs.COMMENT(\n      '^=begin',\n      '^=end',\n      {\n        contains: [ YARDOCTAG ],\n        relevance: 10\n      }\n    ),\n    hljs.COMMENT('^__END__', '\\\\n$')\n  ];\n  const SUBST = {\n    className: 'subst',\n    begin: /#\\{/,\n    end: /\\}/,\n    keywords: RUBY_KEYWORDS\n  };\n  const STRING = {\n    className: 'string',\n    contains: [\n      hljs.BACKSLASH_ESCAPE,\n      SUBST\n    ],\n    variants: [\n      {\n        begin: /'/,\n        end: /'/\n      },\n      {\n        begin: /\"/,\n        end: /\"/\n      },\n      {\n        begin: /`/,\n        end: /`/\n      },\n      {\n        begin: /%[qQwWx]?\\(/,\n        end: /\\)/\n      },\n      {\n        begin: /%[qQwWx]?\\[/,\n        end: /\\]/\n      },\n      {\n        begin: /%[qQwWx]?\\{/,\n        end: /\\}/\n      },\n      {\n        begin: /%[qQwWx]?/\n      },\n      {\n        begin: /%[qQwWx]?\\//,\n        end: /\\//\n      },\n      {\n        begin: /%[qQwWx]?%/,\n        end: /%/\n      },\n      {\n        begin: /%[qQwWx]?-/,\n        end: /-/\n      },\n      {\n        begin: /%[qQwWx]?\\|/,\n        end: /\\|/\n      },\n      // in the following expressions, \\B in the beginning suppresses recognition of ?-sequences\n      // where ? is the last character of a preceding identifier, as in: `func?4`\n      {\n        begin: /\\B\\?(\\\\\\d{1,3})/\n      },\n      {\n        begin: /\\B\\?(\\\\x[A-Fa-f0-9]{1,2})/\n      },\n      {\n        begin: /\\B\\?(\\\\u\\{?[A-Fa-f0-9]{1,6}\\}?)/\n      },\n      {\n        begin: /\\B\\?(\\\\M-\\\\C-|\\\\M-\\\\c|\\\\c\\\\M-|\\\\M-|\\\\C-\\\\M-)[\\x20-\\x7e]/\n      },\n      {\n        begin: /\\B\\?\\\\(c|C-)[\\x20-\\x7e]/\n      },\n      {\n        begin: /\\B\\?\\\\?\\S/\n      },\n      { // heredocs\n        begin: /<<[-~]?'?(\\w+)\\n(?:[^\\n]*\\n)*?\\s*\\1\\b/,\n        returnBegin: true,\n        contains: [\n          {\n            begin: /<<[-~]?'?/\n          },\n          hljs.END_SAME_AS_BEGIN({\n            begin: /(\\w+)/,\n            end: /(\\w+)/,\n            contains: [\n              hljs.BACKSLASH_ESCAPE,\n              SUBST\n            ]\n          })\n        ]\n      }\n    ]\n  };\n\n  // Ruby syntax is underdocumented, but this grammar seems to be accurate\n  // as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)\n  // https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers\n  const decimal = '[1-9](_?[0-9])*|0';\n  const digits = '[0-9](_?[0-9])*';\n  const NUMBER = {\n    className: 'number',\n    relevance: 0,\n    variants: [\n      // decimal integer/float, optionally exponential or rational, optionally imaginary\n      {\n        begin: `\\\\b(${decimal})(\\\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\\\b`\n      },\n\n      // explicit decimal/binary/octal/hexadecimal integer,\n      // optionally rational and/or imaginary\n      {\n        begin: \"\\\\b0[dD][0-9](_?[0-9])*r?i?\\\\b\"\n      },\n      {\n        begin: \"\\\\b0[bB][0-1](_?[0-1])*r?i?\\\\b\"\n      },\n      {\n        begin: \"\\\\b0[oO][0-7](_?[0-7])*r?i?\\\\b\"\n      },\n      {\n        begin: \"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\\\b\"\n      },\n\n      // 0-prefixed implicit octal integer, optionally rational and/or imaginary\n      {\n        begin: \"\\\\b0(_?[0-7])+r?i?\\\\b\"\n      }\n    ]\n  };\n\n  const PARAMS = {\n    className: 'params',\n    begin: '\\\\(',\n    end: '\\\\)',\n    endsParent: true,\n    keywords: RUBY_KEYWORDS\n  };\n\n  const RUBY_DEFAULT_CONTAINS = [\n    STRING,\n    {\n      className: 'class',\n      beginKeywords: 'class module',\n      end: '$|;',\n      illegal: /=/,\n      contains: [\n        hljs.inherit(hljs.TITLE_MODE, {\n          begin: '[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|!)?'\n        }),\n        {\n          begin: '<\\\\s*',\n          contains: [\n            {\n              begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE,\n              // we already get points for <, we don't need poitns\n              // for the name also\n              relevance: 0\n            }\n          ]\n        }\n      ].concat(COMMENT_MODES)\n    },\n    {\n      className: 'function',\n      // def method_name(\n      // def method_name;\n      // def method_name (end of line)\n      begin: concat(/def\\s+/, lookahead(RUBY_METHOD_RE + \"\\\\s*(\\\\(|;|$)\")),\n      relevance: 0, // relevance comes from kewords\n      keywords: \"def\",\n      end: '$|;',\n      contains: [\n        hljs.inherit(hljs.TITLE_MODE, {\n          begin: RUBY_METHOD_RE\n        }),\n        PARAMS\n      ].concat(COMMENT_MODES)\n    },\n    {\n      // swallow namespace qualifiers before symbols\n      begin: hljs.IDENT_RE + '::'\n    },\n    {\n      className: 'symbol',\n      begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\\\?)?:',\n      relevance: 0\n    },\n    {\n      className: 'symbol',\n      begin: ':(?!\\\\s)',\n      contains: [\n        STRING,\n        {\n          begin: RUBY_METHOD_RE\n        }\n      ],\n      relevance: 0\n    },\n    NUMBER,\n    {\n      // negative-look forward attemps to prevent false matches like:\n      // @ident@ or $ident$ that might indicate this is not ruby at all\n      className: \"variable\",\n      begin: '(\\\\$\\\\W)|((\\\\$|@@?)(\\\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`\n    },\n    {\n      className: 'params',\n      begin: /\\|/,\n      end: /\\|/,\n      relevance: 0, // this could be a lot of things (in other languages) other than params\n      keywords: RUBY_KEYWORDS\n    },\n    { // regexp container\n      begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\\\s*',\n      keywords: 'unless',\n      contains: [\n        {\n          className: 'regexp',\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            SUBST\n          ],\n          illegal: /\\n/,\n          variants: [\n            {\n              begin: '/',\n              end: '/[a-z]*'\n            },\n            {\n              begin: /%r\\{/,\n              end: /\\}[a-z]*/\n            },\n            {\n              begin: '%r\\\\(',\n              end: '\\\\)[a-z]*'\n            },\n            {\n              begin: '%r!',\n              end: '![a-z]*'\n            },\n            {\n              begin: '%r\\\\[',\n              end: '\\\\][a-z]*'\n            }\n          ]\n        }\n      ].concat(IRB_OBJECT, COMMENT_MODES),\n      relevance: 0\n    }\n  ].concat(IRB_OBJECT, COMMENT_MODES);\n\n  SUBST.contains = RUBY_DEFAULT_CONTAINS;\n  PARAMS.contains = RUBY_DEFAULT_CONTAINS;\n\n  // >>\n  // ?>\n  const SIMPLE_PROMPT = \"[>?]>\";\n  // irb(main):001:0>\n  const DEFAULT_PROMPT = \"[\\\\w#]+\\\\(\\\\w+\\\\):\\\\d+:\\\\d+>\";\n  const RVM_PROMPT = \"(\\\\w+-)?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(p\\\\d+)?[^\\\\d][^>]+>\";\n\n  const IRB_DEFAULT = [\n    {\n      begin: /^\\s*=>/,\n      starts: {\n        end: '$',\n        contains: RUBY_DEFAULT_CONTAINS\n      }\n    },\n    {\n      className: 'meta',\n      begin: '^(' + SIMPLE_PROMPT + \"|\" + DEFAULT_PROMPT + '|' + RVM_PROMPT + ')(?=[ ])',\n      starts: {\n        end: '$',\n        contains: RUBY_DEFAULT_CONTAINS\n      }\n    }\n  ];\n\n  COMMENT_MODES.unshift(IRB_OBJECT);\n\n  return {\n    name: 'Ruby',\n    aliases: [\n      'rb',\n      'gemspec',\n      'podspec',\n      'thor',\n      'irb'\n    ],\n    keywords: RUBY_KEYWORDS,\n    illegal: /\\/\\*/,\n    contains: [\n      hljs.SHEBANG({\n        binary: \"ruby\"\n      })\n    ]\n      .concat(IRB_DEFAULT)\n      .concat(COMMENT_MODES)\n      .concat(RUBY_DEFAULT_CONTAINS)\n  };\n}\n\nmodule.exports = ruby;\n","/*\nLanguage: Scala\nCategory: functional\nAuthor: Jan Berkel \nContributors: Erik Osheim \nWebsite: https://www.scala-lang.org\n*/\n\nfunction scala(hljs) {\n  const ANNOTATION = {\n    className: 'meta',\n    begin: '@[A-Za-z]+'\n  };\n\n  // used in strings for escaping/interpolation/substitution\n  const SUBST = {\n    className: 'subst',\n    variants: [\n      {\n        begin: '\\\\$[A-Za-z0-9_]+'\n      },\n      {\n        begin: /\\$\\{/,\n        end: /\\}/\n      }\n    ]\n  };\n\n  const STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: '\"\"\"',\n        end: '\"\"\"'\n      },\n      {\n        begin: '\"',\n        end: '\"',\n        illegal: '\\\\n',\n        contains: [ hljs.BACKSLASH_ESCAPE ]\n      },\n      {\n        begin: '[a-z]+\"',\n        end: '\"',\n        illegal: '\\\\n',\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          SUBST\n        ]\n      },\n      {\n        className: 'string',\n        begin: '[a-z]+\"\"\"',\n        end: '\"\"\"',\n        contains: [ SUBST ],\n        relevance: 10\n      }\n    ]\n\n  };\n\n  const SYMBOL = {\n    className: 'symbol',\n    begin: '\\'\\\\w[\\\\w\\\\d_]*(?!\\')'\n  };\n\n  const TYPE = {\n    className: 'type',\n    begin: '\\\\b[A-Z][A-Za-z0-9_]*',\n    relevance: 0\n  };\n\n  const NAME = {\n    className: 'title',\n    begin: /[^0-9\\n\\t \"'(),.`{}\\[\\]:;][^\\n\\t \"'(),.`{}\\[\\]:;]+|[^0-9\\n\\t \"'(),.`{}\\[\\]:;=]/,\n    relevance: 0\n  };\n\n  const CLASS = {\n    className: 'class',\n    beginKeywords: 'class object trait type',\n    end: /[:={\\[\\n;]/,\n    excludeEnd: true,\n    contains: [\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      {\n        beginKeywords: 'extends with',\n        relevance: 10\n      },\n      {\n        begin: /\\[/,\n        end: /\\]/,\n        excludeBegin: true,\n        excludeEnd: true,\n        relevance: 0,\n        contains: [ TYPE ]\n      },\n      {\n        className: 'params',\n        begin: /\\(/,\n        end: /\\)/,\n        excludeBegin: true,\n        excludeEnd: true,\n        relevance: 0,\n        contains: [ TYPE ]\n      },\n      NAME\n    ]\n  };\n\n  const METHOD = {\n    className: 'function',\n    beginKeywords: 'def',\n    end: /[:={\\[(\\n;]/,\n    excludeEnd: true,\n    contains: [ NAME ]\n  };\n\n  return {\n    name: 'Scala',\n    keywords: {\n      literal: 'true false null',\n      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'\n    },\n    contains: [\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      STRING,\n      SYMBOL,\n      TYPE,\n      METHOD,\n      CLASS,\n      hljs.C_NUMBER_MODE,\n      ANNOTATION\n    ]\n  };\n}\n\nmodule.exports = scala;\n","/*\nLanguage: Shell Session\nRequires: bash.js\nAuthor: TSUYUSATO Kitsune \nCategory: common\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction shell(hljs) {\n  return {\n    name: 'Shell Session',\n    aliases: [ 'console' ],\n    contains: [\n      {\n        className: 'meta',\n        // We cannot add \\s (spaces) in the regular expression otherwise it will be too broad and produce unexpected result.\n        // For instance, in the following example, it would match \"echo /path/to/home >\" as a prompt:\n        // echo /path/to/home > t.exe\n        begin: /^\\s{0,3}[/~\\w\\d[\\]()@-]*[>%$#]/,\n        starts: {\n          end: /[^\\\\](?=\\s*$)/,\n          subLanguage: 'bash'\n        }\n      }\n    ]\n  };\n}\n\nmodule.exports = shell;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] } args\n * @returns {string}\n */\nfunction either(...args) {\n  const joined = '(' + args.map((x) => source(x)).join(\"|\") + \")\";\n  return joined;\n}\n\n/*\n Language: SQL\n Website: https://en.wikipedia.org/wiki/SQL\n Category: common, database\n */\n\nfunction sql(hljs) {\n  const COMMENT_MODE = hljs.COMMENT('--', '$');\n  const STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: /'/,\n        end: /'/,\n        contains: [\n          {begin: /''/ }\n        ]\n      }\n    ]\n  };\n  const QUOTED_IDENTIFIER = {\n    begin: /\"/,\n    end: /\"/,\n    contains: [ { begin: /\"\"/ } ]\n  };\n\n  const LITERALS = [\n    \"true\",\n    \"false\",\n    // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.\n    // \"null\",\n    \"unknown\"\n  ];\n\n  const MULTI_WORD_TYPES = [\n    \"double precision\",\n    \"large object\",\n    \"with timezone\",\n    \"without timezone\"\n  ];\n\n  const TYPES = [\n    'bigint',\n    'binary',\n    'blob',\n    'boolean',\n    'char',\n    'character',\n    'clob',\n    'date',\n    'dec',\n    'decfloat',\n    'decimal',\n    'float',\n    'int',\n    'integer',\n    'interval',\n    'nchar',\n    'nclob',\n    'national',\n    'numeric',\n    'real',\n    'row',\n    'smallint',\n    'time',\n    'timestamp',\n    'varchar',\n    'varying', // modifier (character varying)\n    'varbinary'\n  ];\n\n  const NON_RESERVED_WORDS = [\n    \"add\",\n    \"asc\",\n    \"collation\",\n    \"desc\",\n    \"final\",\n    \"first\",\n    \"last\",\n    \"view\"\n  ];\n\n  // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word\n  const RESERVED_WORDS = [\n    \"abs\",\n    \"acos\",\n    \"all\",\n    \"allocate\",\n    \"alter\",\n    \"and\",\n    \"any\",\n    \"are\",\n    \"array\",\n    \"array_agg\",\n    \"array_max_cardinality\",\n    \"as\",\n    \"asensitive\",\n    \"asin\",\n    \"asymmetric\",\n    \"at\",\n    \"atan\",\n    \"atomic\",\n    \"authorization\",\n    \"avg\",\n    \"begin\",\n    \"begin_frame\",\n    \"begin_partition\",\n    \"between\",\n    \"bigint\",\n    \"binary\",\n    \"blob\",\n    \"boolean\",\n    \"both\",\n    \"by\",\n    \"call\",\n    \"called\",\n    \"cardinality\",\n    \"cascaded\",\n    \"case\",\n    \"cast\",\n    \"ceil\",\n    \"ceiling\",\n    \"char\",\n    \"char_length\",\n    \"character\",\n    \"character_length\",\n    \"check\",\n    \"classifier\",\n    \"clob\",\n    \"close\",\n    \"coalesce\",\n    \"collate\",\n    \"collect\",\n    \"column\",\n    \"commit\",\n    \"condition\",\n    \"connect\",\n    \"constraint\",\n    \"contains\",\n    \"convert\",\n    \"copy\",\n    \"corr\",\n    \"corresponding\",\n    \"cos\",\n    \"cosh\",\n    \"count\",\n    \"covar_pop\",\n    \"covar_samp\",\n    \"create\",\n    \"cross\",\n    \"cube\",\n    \"cume_dist\",\n    \"current\",\n    \"current_catalog\",\n    \"current_date\",\n    \"current_default_transform_group\",\n    \"current_path\",\n    \"current_role\",\n    \"current_row\",\n    \"current_schema\",\n    \"current_time\",\n    \"current_timestamp\",\n    \"current_path\",\n    \"current_role\",\n    \"current_transform_group_for_type\",\n    \"current_user\",\n    \"cursor\",\n    \"cycle\",\n    \"date\",\n    \"day\",\n    \"deallocate\",\n    \"dec\",\n    \"decimal\",\n    \"decfloat\",\n    \"declare\",\n    \"default\",\n    \"define\",\n    \"delete\",\n    \"dense_rank\",\n    \"deref\",\n    \"describe\",\n    \"deterministic\",\n    \"disconnect\",\n    \"distinct\",\n    \"double\",\n    \"drop\",\n    \"dynamic\",\n    \"each\",\n    \"element\",\n    \"else\",\n    \"empty\",\n    \"end\",\n    \"end_frame\",\n    \"end_partition\",\n    \"end-exec\",\n    \"equals\",\n    \"escape\",\n    \"every\",\n    \"except\",\n    \"exec\",\n    \"execute\",\n    \"exists\",\n    \"exp\",\n    \"external\",\n    \"extract\",\n    \"false\",\n    \"fetch\",\n    \"filter\",\n    \"first_value\",\n    \"float\",\n    \"floor\",\n    \"for\",\n    \"foreign\",\n    \"frame_row\",\n    \"free\",\n    \"from\",\n    \"full\",\n    \"function\",\n    \"fusion\",\n    \"get\",\n    \"global\",\n    \"grant\",\n    \"group\",\n    \"grouping\",\n    \"groups\",\n    \"having\",\n    \"hold\",\n    \"hour\",\n    \"identity\",\n    \"in\",\n    \"indicator\",\n    \"initial\",\n    \"inner\",\n    \"inout\",\n    \"insensitive\",\n    \"insert\",\n    \"int\",\n    \"integer\",\n    \"intersect\",\n    \"intersection\",\n    \"interval\",\n    \"into\",\n    \"is\",\n    \"join\",\n    \"json_array\",\n    \"json_arrayagg\",\n    \"json_exists\",\n    \"json_object\",\n    \"json_objectagg\",\n    \"json_query\",\n    \"json_table\",\n    \"json_table_primitive\",\n    \"json_value\",\n    \"lag\",\n    \"language\",\n    \"large\",\n    \"last_value\",\n    \"lateral\",\n    \"lead\",\n    \"leading\",\n    \"left\",\n    \"like\",\n    \"like_regex\",\n    \"listagg\",\n    \"ln\",\n    \"local\",\n    \"localtime\",\n    \"localtimestamp\",\n    \"log\",\n    \"log10\",\n    \"lower\",\n    \"match\",\n    \"match_number\",\n    \"match_recognize\",\n    \"matches\",\n    \"max\",\n    \"member\",\n    \"merge\",\n    \"method\",\n    \"min\",\n    \"minute\",\n    \"mod\",\n    \"modifies\",\n    \"module\",\n    \"month\",\n    \"multiset\",\n    \"national\",\n    \"natural\",\n    \"nchar\",\n    \"nclob\",\n    \"new\",\n    \"no\",\n    \"none\",\n    \"normalize\",\n    \"not\",\n    \"nth_value\",\n    \"ntile\",\n    \"null\",\n    \"nullif\",\n    \"numeric\",\n    \"octet_length\",\n    \"occurrences_regex\",\n    \"of\",\n    \"offset\",\n    \"old\",\n    \"omit\",\n    \"on\",\n    \"one\",\n    \"only\",\n    \"open\",\n    \"or\",\n    \"order\",\n    \"out\",\n    \"outer\",\n    \"over\",\n    \"overlaps\",\n    \"overlay\",\n    \"parameter\",\n    \"partition\",\n    \"pattern\",\n    \"per\",\n    \"percent\",\n    \"percent_rank\",\n    \"percentile_cont\",\n    \"percentile_disc\",\n    \"period\",\n    \"portion\",\n    \"position\",\n    \"position_regex\",\n    \"power\",\n    \"precedes\",\n    \"precision\",\n    \"prepare\",\n    \"primary\",\n    \"procedure\",\n    \"ptf\",\n    \"range\",\n    \"rank\",\n    \"reads\",\n    \"real\",\n    \"recursive\",\n    \"ref\",\n    \"references\",\n    \"referencing\",\n    \"regr_avgx\",\n    \"regr_avgy\",\n    \"regr_count\",\n    \"regr_intercept\",\n    \"regr_r2\",\n    \"regr_slope\",\n    \"regr_sxx\",\n    \"regr_sxy\",\n    \"regr_syy\",\n    \"release\",\n    \"result\",\n    \"return\",\n    \"returns\",\n    \"revoke\",\n    \"right\",\n    \"rollback\",\n    \"rollup\",\n    \"row\",\n    \"row_number\",\n    \"rows\",\n    \"running\",\n    \"savepoint\",\n    \"scope\",\n    \"scroll\",\n    \"search\",\n    \"second\",\n    \"seek\",\n    \"select\",\n    \"sensitive\",\n    \"session_user\",\n    \"set\",\n    \"show\",\n    \"similar\",\n    \"sin\",\n    \"sinh\",\n    \"skip\",\n    \"smallint\",\n    \"some\",\n    \"specific\",\n    \"specifictype\",\n    \"sql\",\n    \"sqlexception\",\n    \"sqlstate\",\n    \"sqlwarning\",\n    \"sqrt\",\n    \"start\",\n    \"static\",\n    \"stddev_pop\",\n    \"stddev_samp\",\n    \"submultiset\",\n    \"subset\",\n    \"substring\",\n    \"substring_regex\",\n    \"succeeds\",\n    \"sum\",\n    \"symmetric\",\n    \"system\",\n    \"system_time\",\n    \"system_user\",\n    \"table\",\n    \"tablesample\",\n    \"tan\",\n    \"tanh\",\n    \"then\",\n    \"time\",\n    \"timestamp\",\n    \"timezone_hour\",\n    \"timezone_minute\",\n    \"to\",\n    \"trailing\",\n    \"translate\",\n    \"translate_regex\",\n    \"translation\",\n    \"treat\",\n    \"trigger\",\n    \"trim\",\n    \"trim_array\",\n    \"true\",\n    \"truncate\",\n    \"uescape\",\n    \"union\",\n    \"unique\",\n    \"unknown\",\n    \"unnest\",\n    \"update   \",\n    \"upper\",\n    \"user\",\n    \"using\",\n    \"value\",\n    \"values\",\n    \"value_of\",\n    \"var_pop\",\n    \"var_samp\",\n    \"varbinary\",\n    \"varchar\",\n    \"varying\",\n    \"versioning\",\n    \"when\",\n    \"whenever\",\n    \"where\",\n    \"width_bucket\",\n    \"window\",\n    \"with\",\n    \"within\",\n    \"without\",\n    \"year\",\n  ];\n\n  // these are reserved words we have identified to be functions\n  // and should only be highlighted in a dispatch-like context\n  // ie, array_agg(...), etc.\n  const RESERVED_FUNCTIONS = [\n    \"abs\",\n    \"acos\",\n    \"array_agg\",\n    \"asin\",\n    \"atan\",\n    \"avg\",\n    \"cast\",\n    \"ceil\",\n    \"ceiling\",\n    \"coalesce\",\n    \"corr\",\n    \"cos\",\n    \"cosh\",\n    \"count\",\n    \"covar_pop\",\n    \"covar_samp\",\n    \"cume_dist\",\n    \"dense_rank\",\n    \"deref\",\n    \"element\",\n    \"exp\",\n    \"extract\",\n    \"first_value\",\n    \"floor\",\n    \"json_array\",\n    \"json_arrayagg\",\n    \"json_exists\",\n    \"json_object\",\n    \"json_objectagg\",\n    \"json_query\",\n    \"json_table\",\n    \"json_table_primitive\",\n    \"json_value\",\n    \"lag\",\n    \"last_value\",\n    \"lead\",\n    \"listagg\",\n    \"ln\",\n    \"log\",\n    \"log10\",\n    \"lower\",\n    \"max\",\n    \"min\",\n    \"mod\",\n    \"nth_value\",\n    \"ntile\",\n    \"nullif\",\n    \"percent_rank\",\n    \"percentile_cont\",\n    \"percentile_disc\",\n    \"position\",\n    \"position_regex\",\n    \"power\",\n    \"rank\",\n    \"regr_avgx\",\n    \"regr_avgy\",\n    \"regr_count\",\n    \"regr_intercept\",\n    \"regr_r2\",\n    \"regr_slope\",\n    \"regr_sxx\",\n    \"regr_sxy\",\n    \"regr_syy\",\n    \"row_number\",\n    \"sin\",\n    \"sinh\",\n    \"sqrt\",\n    \"stddev_pop\",\n    \"stddev_samp\",\n    \"substring\",\n    \"substring_regex\",\n    \"sum\",\n    \"tan\",\n    \"tanh\",\n    \"translate\",\n    \"translate_regex\",\n    \"treat\",\n    \"trim\",\n    \"trim_array\",\n    \"unnest\",\n    \"upper\",\n    \"value_of\",\n    \"var_pop\",\n    \"var_samp\",\n    \"width_bucket\",\n  ];\n\n  // these functions can\n  const POSSIBLE_WITHOUT_PARENS = [\n    \"current_catalog\",\n    \"current_date\",\n    \"current_default_transform_group\",\n    \"current_path\",\n    \"current_role\",\n    \"current_schema\",\n    \"current_transform_group_for_type\",\n    \"current_user\",\n    \"session_user\",\n    \"system_time\",\n    \"system_user\",\n    \"current_time\",\n    \"localtime\",\n    \"current_timestamp\",\n    \"localtimestamp\"\n  ];\n\n  // those exist to boost relevance making these very\n  // \"SQL like\" keyword combos worth +1 extra relevance\n  const COMBOS = [\n    \"create table\",\n    \"insert into\",\n    \"primary key\",\n    \"foreign key\",\n    \"not null\",\n    \"alter table\",\n    \"add constraint\",\n    \"grouping sets\",\n    \"on overflow\",\n    \"character set\",\n    \"respect nulls\",\n    \"ignore nulls\",\n    \"nulls first\",\n    \"nulls last\",\n    \"depth first\",\n    \"breadth first\"\n  ];\n\n  const FUNCTIONS = RESERVED_FUNCTIONS;\n\n  const KEYWORDS = [...RESERVED_WORDS, ...NON_RESERVED_WORDS].filter((keyword) => {\n    return !RESERVED_FUNCTIONS.includes(keyword);\n  });\n\n  const VARIABLE = {\n    className: \"variable\",\n    begin: /@[a-z0-9]+/,\n  };\n\n  const OPERATOR = {\n    className: \"operator\",\n    begin: /[-+*/=%^~]|&&?|\\|\\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,\n    relevance: 0,\n  };\n\n  const FUNCTION_CALL = {\n    begin: concat(/\\b/, either(...FUNCTIONS), /\\s*\\(/),\n    keywords: {\n      built_in: FUNCTIONS\n    }\n  };\n\n  // keywords with less than 3 letters are reduced in relevancy\n  function reduceRelevancy(list, {exceptions, when} = {}) {\n    const qualifyFn = when;\n    exceptions = exceptions || [];\n    return list.map((item) => {\n      if (item.match(/\\|\\d+$/) || exceptions.includes(item)) {\n        return item;\n      } else if (qualifyFn(item)) {\n        return `${item}|0`;\n      } else {\n        return item;\n      }\n    });\n  }\n\n  return {\n    name: 'SQL',\n    case_insensitive: true,\n    // does not include {} or HTML tags ` x.length < 3 }),\n      literal: LITERALS,\n      type: TYPES,\n      built_in: POSSIBLE_WITHOUT_PARENS\n    },\n    contains: [\n      {\n        begin: either(...COMBOS),\n        keywords: {\n          $pattern: /[\\w\\.]+/,\n          keyword: KEYWORDS.concat(COMBOS),\n          literal: LITERALS,\n          type: TYPES\n        },\n      },\n      {\n        className: \"type\",\n        begin: either(...MULTI_WORD_TYPES)\n      },\n      FUNCTION_CALL,\n      VARIABLE,\n      STRING,\n      QUOTED_IDENTIFIER,\n      hljs.C_NUMBER_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      COMMENT_MODE,\n      OPERATOR\n    ]\n  };\n}\n\nmodule.exports = sql;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction optional(re) {\n  return concat('(', re, ')?');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] } args\n * @returns {string}\n */\nfunction either(...args) {\n  const joined = '(' + args.map((x) => source(x)).join(\"|\") + \")\";\n  return joined;\n}\n\n/*\nLanguage: HTML, XML\nWebsite: https://www.w3.org/XML/\nCategory: common\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction xml(hljs) {\n  // Element names can contain letters, digits, hyphens, underscores, and periods\n  const TAG_NAME_RE = concat(/[A-Z_]/, optional(/[A-Z0-9_.-]*:/), /[A-Z0-9_.-]*/);\n  const XML_IDENT_RE = /[A-Za-z0-9._:-]+/;\n  const XML_ENTITIES = {\n    className: 'symbol',\n    begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/\n  };\n  const XML_META_KEYWORDS = {\n    begin: /\\s/,\n    contains: [\n      {\n        className: 'meta-keyword',\n        begin: /#?[a-z_][a-z1-9_-]+/,\n        illegal: /\\n/\n      }\n    ]\n  };\n  const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {\n    begin: /\\(/,\n    end: /\\)/\n  });\n  const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {\n    className: 'meta-string'\n  });\n  const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {\n    className: 'meta-string'\n  });\n  const TAG_INTERNALS = {\n    endsWithParent: true,\n    illegal: /`]+/\n              }\n            ]\n          }\n        ]\n      }\n    ]\n  };\n  return {\n    name: 'HTML, XML',\n    aliases: [\n      'html',\n      'xhtml',\n      'rss',\n      'atom',\n      'xjb',\n      'xsd',\n      'xsl',\n      'plist',\n      'wsf',\n      'svg'\n    ],\n    case_insensitive: true,\n    contains: [\n      {\n        className: 'meta',\n        begin: //,\n        relevance: 10,\n        contains: [\n          XML_META_KEYWORDS,\n          QUOTE_META_STRING_MODE,\n          APOS_META_STRING_MODE,\n          XML_META_PAR_KEYWORDS,\n          {\n            begin: /\\[/,\n            end: /\\]/,\n            contains: [\n              {\n                className: 'meta',\n                begin: //,\n                contains: [\n                  XML_META_KEYWORDS,\n                  XML_META_PAR_KEYWORDS,\n                  QUOTE_META_STRING_MODE,\n                  APOS_META_STRING_MODE\n                ]\n              }\n            ]\n          }\n        ]\n      },\n      hljs.COMMENT(\n        //,\n        {\n          relevance: 10\n        }\n      ),\n      {\n        begin: //,\n        relevance: 10\n      },\n      XML_ENTITIES,\n      {\n        className: 'meta',\n        begin: /<\\?xml/,\n        end: /\\?>/,\n        relevance: 10\n      },\n      {\n        className: 'tag',\n        /*\n        The lookahead pattern (?=...) ensures that 'begin' only matches\n        ')/,\n        end: />/,\n        keywords: {\n          name: 'style'\n        },\n        contains: [ TAG_INTERNALS ],\n        starts: {\n          end: /<\\/style>/,\n          returnEnd: true,\n          subLanguage: [\n            'css',\n            'xml'\n          ]\n        }\n      },\n      {\n        className: 'tag',\n        // See the comment in the 
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + + + + +
+ + +For spring-boot v3 support, make sure you use springdoc-openapi v2 +
+
+
+

springdoc-openapi is on Open Collective. If you ❤️ this project consider becoming a sponsor.

+
+
+

This project is sponsored by

+
+

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

+
+
+
+

1. Introduction

+
+
+

springdoc-openapi java library helps to automate the generation of API documentation using spring boot projects. +springdoc-openapi works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations.

+
+
+

Automatically generates documentation in JSON/YAML and HTML format APIs. +This documentation can be completed by comments using swagger-api annotations.

+
+
+

This library supports:

+
+
+
    +
  • +

    OpenAPI 3

    +
  • +
  • +

    Spring-boot (v1, v2 and v3)

    +
  • +
  • +

    JSR-303, specifically for @NotNull, @Min, @Max, and @Size.

    +
  • +
  • +

    Swagger-ui

    +
  • +
  • +

    OAuth 2

    +
  • +
  • +

    GraalVM native images

    +
  • +
+
+
+

The following video introduces the Library:

+
+
+
+spring.io conference +
+
+
+

This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal).

+
+
+
+
+

2. Getting Started

+
+
+

For the integration between spring-boot and swagger-ui, add the library to the list of your project dependencies (No additional configuration is needed)

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-ui</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+

This will automatically deploy swagger-ui to a spring-boot application:

+
+
+
    +
  • +

    Documentation will be available in HTML format, using the official swagger-ui jars

    +
  • +
  • +

    The Swagger UI page will then be available at http://server:port/context-path/swagger-ui.html and the OpenAPI description will be available at the following url for json format: http://server:port/context-path/v3/api-docs

    +
    +
      +
    • +

      server: The server name or IP

      +
    • +
    • +

      port: The server port

      +
    • +
    • +

      context-path: The context path of the application

      +
    • +
    +
    +
  • +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
+
+
+ + + + + +
+ + +For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: . +
+
+
+
+
# swagger-ui custom path
+springdoc.swagger-ui.path=/swagger-ui.html
+
+
+
+
+
+

3. Springdoc-openapi Modules

+
+
+

3.1. General overview

+
+
+Architecture +
+
+
+
+

3.2. Spring WebMvc support

+
+
    +
  • +

    Documentation will be available at the following url for json format: http://server:port/context-path/v3/api-docs

    +
    +
      +
    • +

      server: The server name or IP

      +
    • +
    • +

      port: The server port

      +
    • +
    • +

      context-path: The context path of the application

      +
    • +
    +
    +
  • +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
  • +

    Add the library to the list of your project dependencies. (No additional configuration is needed)

    +
  • +
+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-webmvc-core</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+ + + + + +
+ + +This dependency is relevant if you want to generate the OpenAPI description without using the swagger-ui. +
+
+
+ + + + + +
+ + +For custom path of the OpenAPI documentation in Json format, add a custom springdoc property, in your spring-boot configuration file: +
+
+
+
+
# /api-docs endpoint custom path
+springdoc.api-docs.path=/api-docs
+
+
+
+
+

3.3. Spring WebFlux support

+
+
    +
  • +

    Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml

    +
  • +
  • +

    Add the library to the list of your project dependencies (No additional configuration is needed)

    +
  • +
+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-webflux-ui</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
+

3.4. Spring Hateoas support

+
+

The support for Spring Hateoas is available using the dependency springdoc-openapi-hateoas. +The projects that use Spring Hateoas should combine this dependency with the springdoc-openapi-ui dependency. +This dependency enables the support of Spring Hateoas format.

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-hateoas</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
+

3.5. Spring Data Rest support

+
+

The projects that use spring-data-rest can add the following dependency in combination with the springdoc-openapi-ui dependency. +This dependency enables the support of spring-boot-starter-data-rest types like: @RepositoryRestResource and QuerydslPredicate annotations.

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-data-rest</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
+

3.6. Spring Security support

+
+

For a project that uses spring-security, you should add the following dependency, in combination with the springdoc-openapi-ui dependency: +This dependency helps ignoring @AuthenticationPrincipal in case its used on REST Controllers.

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-security</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
+

3.7. Actuator support

+
+
    +
  • +

    In order to display spring-boot-actuator endpoints, simply add the following property:

    +
  • +
+
+
+
+
springdoc.show-actuator=true
+
+
+
+

Starting from the release 1.5.1, it will be possible to expose the swagger-ui and the openapi endpoints on actuator port.

+
+
+ + + + + +
+ + +The actuator management port has to be different from the application port. +
+
+
+

To expose the swagger-ui, on the management port, you should set

+
+
+
+
springdoc.use-management-port=true
+# This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path.
+management.endpoints.web.exposure.include=openapi, swagger-ui
+
+
+
+

Once enabled, you should also be able to see the springdoc-openapi endpoints under: (host and port depends on your settings) +- http://serverName:managementPort/actuator

+
+
+

For example, if you have the following settings:

+
+
+

Two endpoints will be available:

+
+
+
    +
  1. +

    REST API that holdes the OpenAPI definition:

    +
    +
      +
    • +

      http://serverName:managementPort/actuator/openapi

      +
    • +
    +
    +
  2. +
  3. +

    An Endpoint, that routes to the swagger-ui:

    +
    +
      +
    • +

      http://serverName:managementPort/actuator/swagger-ui

      +
    • +
    +
    +
  4. +
+
+
+
+
management.server.port=9090
+
+
+
+

For the example, you should also be able to see the springdoc-openapi endpoints:

+
+
+
    +
  • +

    http://serverName:9090/actuator

    +
  • +
  • +

    http://serverName:9090/actuator/swagger-ui

    +
  • +
  • +

    http://serverName:9090/actuator/openapi

    +
  • +
+
+
+

All the path springdoc-openapi properties are not applicable when springdoc.use-management-port=true.

+
+
+ + + + + +
+ + +If you want to reach the application endpoints, from the swagger-ui deployed beneath the actuator base path, using a different port from your application, CORS for your endpoints on your application level should be enabled. +
+
+
+

Additionally, it is also possible to combine this property, with the existing property to display the actuator endpoints in the swagger-ui.

+
+
+
+
springdoc.show-actuator=true
+
+
+
+

Once enabled: +- A dedicated group for the actuator endpoints will be by default added. +- If no group is defined for the application, a default one will be added.

+
+
+

The swagger-ui will be then accessible through the actuator port:

+
+
+
    +
  • +

    http://serverName:managementPort/actuator/swagger-ui

    +
  • +
+
+
+

If the management port is different from the application port and springdoc.use-management-port is not defined but springdoc.show-actuator is set to true:

+
+
+
    +
  • +

    The swagger-ui will be then accessible through the application port. For example: http://serverName:applicationPort/swagger-ui.html

    +
  • +
  • +

    A dedicated group for the actuator endpoints will be by default added.

    +
  • +
  • +

    If no group is defined for the application, a default one will be added.

    +
  • +
+
+
+ + + + + +
+ + +If you want to reach the actuator endpoints for this case (different port from your application), CORS for your actuator endpoints should be enabled. +
+
+
+

Note: The naming of these new endpoints beneath the actuator base path cannot be customized for now.

+
+
+
+

3.8. Spring Cloud Function Web support

+
+

spring-cloud-function-web exposes Java Function as REST endpoint automatically. +* Since version v1.6.3, the support of functional endpoints has been added.

+
+
+
    +
  • +

    These starters will display the OpenAPI description of the spring-cloud-function-web endpoints.

    +
    +
      +
    • +

      If you are using spring-web, simply add the springdoc-openapi-ui dependency.

      +
    • +
    • +

      If you are using spring-webflux, simply add the springdoc-openapi-webflux-ui dependency.

      +
    • +
    +
    +
  • +
+
+
+

The customisation of the output can be achieved programmatically through OpenApiCustomizer or with the annotations: @RouterOperations and @RouterOperation. +For annotation usage, you have: +* @RouterOperation: It can be used alone, if the customisation is related to a single REST API. +When using @RouterOperation, it’s not mandatory to fill the path

+
+
+
    +
  • +

    @RouterOperation, contains the @Operation annotation. +The @Operation annotation can also be placed on the bean method level if the property beanMethod is declared.

    +
  • +
+
+
+ + + + + +
+ + +Don’t forget to set operationId which is mandatory. +
+
+
+
+
@Bean
+@RouterOperation(operation = @Operation(description = "Say hello", operationId = "hello", tags = "persons",
+        responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = PersonDTO.class)))))
+public Supplier<PersonDTO> helloSupplier() {
+    return () -> new PersonDTO();
+}
+
+
+
+
+
    +
  • +

    @RouterOperations: This annotation should be used to describe the multiple REST APIs exposed by spring-cloud-function-web. +When using RouterOperations, it’s mandatory to fill the method property.

    +
  • +
  • +

    A @RouterOperations, contains many @RouterOperation.

    +
  • +
+
+
+
+
@Bean
+@RouterOperations({
+        @RouterOperation(method = RequestMethod.GET, operation = @Operation(description = "Say hello GET", operationId = "lowercaseGET", tags = "persons")),
+        @RouterOperation(method = RequestMethod.POST, operation = @Operation(description = "Say hello POST", operationId = "lowercasePOST", tags = "positions"))
+})
+public Function<Flux<String>, Flux<String>> lowercase() {
+    return flux -> flux.map(value -> value.toLowerCase());
+}
+
+
+
+
+

Some code samples are available on GITHUB of demos:

+
+ +
+
+

3.9. Kotlin support

+
+

For a project that uses Kotlin, you should add the following dependency. +This dependency improves the support of Kotlin types:

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-kotlin</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
    +
  • +

    If you are using spring-web, you should combine the springdoc-openapi-kotlin module with springdoc-openapi-ui.

    +
  • +
  • +

    If you are using spring-webflux, you should combine the springdoc-openapi-kotlin module with springdoc-openapi-webflux-ui.

    +
  • +
+
+
+
+

3.10. Groovy support

+
+

For a project that uses Groovy, you should add the following dependency, in combination with the springdoc-openapi-ui dependency: +This dependency improves the support of Kotlin types:

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-groovy</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
+

3.11. Javadoc support

+
+

For a project that wants to enable javadoc support, you should add the following dependency, in combination with the springdoc-openapi-ui dependency:

+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-javadoc</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+

This dependency improves the support of javadoc tags and comments:

+
+
+
    +
  • +

    The javadoc comment of a method: is resolved as the @Operation description

    +
  • +
  • +

    @return : is resolved as the @Operation response description

    +
  • +
  • +

    The javadoc comment of an attribute: is resolved as '@Schema' description for this field.

    +
  • +
+
+
+

This dependency is based on the library therapi-runtime-javadoc

+
+
+ + + + + +
+ + +Make sure, you enable the annotation processor of therapi-runtime-javadoc in order to enable javadoc support for springdoc-openapi. +
+
+
+
+
    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>com.github.therapi</groupId>
+                            <artifactId>therapi-runtime-javadoc-scribe</artifactId>
+                            <version>0.15.0</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+
+
+ + + + + +
+ + +If both a swagger-annotation description and a javadoc comment are present. The value of the swagger-annotation description will be used. +
+
+
+
+
+
+

4. Springdoc-openapi Features

+
+
+

4.1. Adding API Information and Security documentation

+
+

The library uses spring-boot application auto-configured packages to scan for the following annotations in spring beans: OpenAPIDefinition and Info. +These annotations declare, API Information: Title, version, licence, security, servers, tags, security and externalDocs. +For better performance of documentation generation, declare @OpenAPIDefinition and @SecurityScheme annotations within a spring managed bean.

+
+
+
+

4.2. Error Handling for REST using @ControllerAdvice

+
+

To generate documentation automatically, make sure all the methods declare the HTTP Code responses using the annotation: @ResponseStatus

+
+
+
+

4.3. Disabling the springdoc-openapi endpoints

+
+

In order to disable the springdoc-openapi endpoint (/v3/api-docs by default) use the following property:

+
+
+
+
# Disabling the /v3/api-docs endpoint
+springdoc.api-docs.enabled=false
+
+
+
+
+

4.4. Disabling the swagger-ui

+
+

In order to disable the swagger-ui, use the following property:

+
+
+
+
# Disabling the swagger-ui
+springdoc.swagger-ui.enabled=false
+
+
+
+
+

4.5. Swagger-ui configuration

+
+

The library supports the swagger-ui official properties:

+
+ +
+

You need to declare swagger-ui properties as spring-boot properties. +All these properties should be declared with the following prefix: springdoc.swagger-ui

+
+
+
+

4.6. Selecting the Rest Controllers to include in the documentation

+
+

Additionally, to @Hidden annotation from swagger-annotations, its possible to restrict the generated OpenAPI description using package or path configuration.

+
+
+

For the list of packages to include, use the following property:

+
+
+
+
# Packages to include
+springdoc.packagesToScan=com.package1, com.package2
+
+
+
+

For the list of paths to include, use the following property:

+
+
+
+
# Paths to include
+springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
+

4.7. Spring-webflux/WebMvc.fn with Functional Endpoints

+
+

Since version v1.5.0, a functional DSL has been introduced, thanks to this enhancement in the spring-framework: #25938

+
+
+

It’s an alternative functional API to the @RouterOperations annotations.

+
+
+

This is a sample DSL, to generate OpenAPI description to the webflux/WebMvc.fn REST endpoints:

+
+
+
+
@Bean
+RouterFunction<?> routes() {
+    return route().GET("/foo", HANDLER_FUNCTION, ops -> ops
+            .operationId("hello")
+            .parameter(parameterBuilder().name("key1").description("My key1 description"))
+            .parameter(parameterBuilder().name("key2").description("My key2 description"))
+            .response(responseBuilder().responseCode("200").description("This is normal response description"))
+            .response(responseBuilder().responseCode("404").description("This is another response description"))
+    ).build();
+}
+
+
+
+
+

Here is the link for some sample codes:

+
+ +
+

And the Demo code, using the functional endpoints DSL:

+
+ +
+

Since version v1.3.8, the support of functional endpoints has been added. +Two main annotations have been added for this purpose: @RouterOperations and @RouterOperation.

+
+
+

Only REST APIs with the @RouterOperations and @RouterOperation can be displayed on the swagger-ui.

+
+
+
    +
  • +

    @RouterOperation: It can be used alone, if the Router bean contains one single route related to the REST API.. +When using @RouterOperation, its not mandatory to fill the path

    +
  • +
  • +

    @RouterOperation, can reference directly a spring Bean (beanClass property) and the underlying method (beanMethod property): Springdoc-openapi, will then inspect this method and the swagger annotations on this method level.

    +
  • +
+
+
+
+
@Bean
+@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees")
+RouterFunction<ServerResponse> getAllEmployeesRoute() {
+   return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)),
+         req -> ok().body(
+               employeeService().findAllEmployees(), Employee.class));
+}
+
+
+
+
+
    +
  • +

    @RouterOperation, contains the @Operation annotation. +The @Operation annotation can also be placed on the bean method level if the property beanMethod is declared.

    +
  • +
+
+
+ + + + + +
+ + +Don’t forget to set operationId which is mandatory. +
+
+
+
+
@Bean
+@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" },
+      parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") },
+      responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))),
+            @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"),
+            @ApiResponse(responseCode = "404", description = "Employee not found") }))
+RouterFunction<ServerResponse> getEmployeeByIdRoute() {
+   return route(GET("/employees/{id}"),
+         req -> ok().body(
+               employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
+}
+
+
+
+
+
    +
  • +

    @RouterOperations: This annotation should be used if the Router bean contains multiple routes. +When using RouterOperations, its mandatory to fill the path property.

    +
  • +
  • +

    A @RouterOperations, contains many @RouterOperation.

    +
  • +
+
+
+
+
@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
+      @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
+      @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
+      @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
+@Bean
+public RouterFunction<ServerResponse> personRoute(PersonHandler handler) {
+   return RouterFunctions
+         .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
+         .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
+         .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
+         .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
+}
+
+
+
+
+

All the documentations filled using @RouterOperation, might be completed by the router function data. +For that, @RouterOperation fields must help identify uniquely the concerned route. +springdoc-openpi scans for a unique route related to a @RouterOperation annotation, using on the following criteria:

+
+
+
    +
  • +

    by path

    +
  • +
  • +

    by path and RequestMethod

    +
  • +
  • +

    by path and produces

    +
  • +
  • +

    by path and consumes

    +
  • +
  • +

    by path and RequestMethod and produces

    +
  • +
  • +

    by path and RequestMethod and consumes

    +
  • +
  • +

    by path and produces and consumes

    +
  • +
  • +

    by path and RequestMethod and produces and consumes

    +
  • +
+
+
+

Some code samples are available on GITHUB of demos:

+
+ +
+

And some project tests: (from app69 to app75)

+
+ +
+
+

4.8. Integration with WildFly

+
+
    +
  • +

    For WildFly users, you need to add the following dependency to make the swagger-ui work:

    +
  • +
+
+
+
+
   <dependency>
+     <groupId>org.webjars</groupId>
+     <artifactId>webjars-locator-jboss-vfs</artifactId>
+     <version>0.1.0</version>
+   </dependency>
+
+
+
+
+
+
+

5. Springdoc-openapi Properties

+
+
+

springdoc-openapi relies on standard spring configuration properties (yml or properties) using the standard files locations.

+
+
+

5.1. springdoc-openapi core properties

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameDefault ValueDescription

springdoc.api-docs.path

/v3/api-docs

String, For custom path of the OpenAPI documentation in Json format.

springdoc.api-docs.enabled

true

Boolean. To disable the springdoc-openapi endpoint (/v3/api-docs by default).

springdoc.packages-to-scan

*

List of Strings.The list of packages to scan (comma separated)

springdoc.paths-to-match

/*

List of Strings.The list of paths to match (comma separated)

springdoc.produces-to-match

/*

List of Strings.The list of produces mediaTypes to match (comma separated)

springdoc.headers-to-match

/*

List of Strings.The list of headers to match (comma separated)

springdoc.consumes-to-match

/*

List of Strings.The list of consumes mediaTypes to match (comma separated)

springdoc.paths-to-exclude

List of Strings.The list of paths to exclude (comma separated)

springdoc.packages-to-exclude

List of Strings.The list of packages to exclude (comma separated)

springdoc.default-consumes-media-type

application/json

String. The default consumes media type.

springdoc.default-produces-media-type

/

String.The default produces media type.

springdoc.cache.disabled

false

Boolean. To disable the springdoc-openapi cache of the calculated OpenAPI.

springdoc.show-actuator

false

Boolean. To display the actuator endpoints.

springdoc.auto-tag-classes

true

Boolean. To disable the springdoc-openapi automatic tags.

springdoc.model-and-view-allowed

false

Boolean. To allow RestControllers with ModelAndView return to appear in the OpenAPI description.

springdoc.override-with-generic-response

true

Boolean. When true, automatically adds @ControllerAdvice responses to all the generated responses.

springdoc.group-configs[0].group

String.The group name

springdoc.group-configs[0].display-name

String.The display name of the group.

springdoc.group-configs[0].packages-to-scan

*

List of Strings.The list of packages to scan for a group (comma separated)

springdoc.group-configs[0].paths-to-match

/*

List of Strings.The list of paths to match for a group(comma separated)

springdoc.group-configs[0].paths-to-exclude

``

List of Strings.The list of paths to exclude for a group(comma separated)

springdoc.group-configs[0].packages-to-exclude

List of Strings.The list of packages to exclude for a group(comma separated)

springdoc.group-configs[0].produces-to-match

/*

List of Strings.The list of produces mediaTypes to match (comma separated)

springdoc.group-configs[0].consumes-to-match

/*

List of Strings.The list of consumes mediaTypes to match (comma separated)

springdoc.group-configs[0].headers-to-match

/*

List of Strings.The list of headers to match (comma separated)

springdoc.webjars.prefix

/webjars

String, To change the webjars prefix that is visible the URL of swagger-ui for spring-webflux.

springdoc.api-docs.resolve-schema-properties

false

Boolean. To enable property resolver on @Schema (name, title and description).

springdoc.remove-broken-reference-definitions

true

Boolean. To disable removal of broken reference definitions.

springdoc.writer-with-default-pretty-printer

false

Boolean. To enable pretty print of the OpenApi specification.

springdoc.model-converters.deprecating-converter.enabled

true

Boolean. To disable deprecating model converter.

springdoc.model-converters.polymorphic-converter.enabled

true

Boolean. To disable polymorphic model converter.

springdoc.model-converters.pageable-converter.enabled

true

Boolean. To disable pageable model converter.

springdoc.model-converters.sort-converter.enabled

true

Boolean. To disable Sort converter.

springdoc.use-fqn

false

Boolean. To enable fully qualified names.

springdoc.show-login-endpoint

false

Boolean. To make spring security login-endpoint visible.

springdoc.pre-loading-enabled

false

Boolean. Pre-loading setting to load OpenAPI on application startup.

springdoc.pre-loading-locales

List of Strings.The list of locales to load OpenAPI on application startup.(comma separated) If not specified, it will preload with the default Locale.

springdoc.writer-with-order-by-keys

false

Boolean. Enable a deterministic/alphabetical ordering.

springdoc.use-management-port

false

Boolean. To expose the swagger-ui on the actuator management port.

springdoc.disable-i18n

false

Boolean. To disable automatic translation using i18n.

springdoc.show-spring-cloud-functions

true

Boolean. To display the spring-cloud-function web endpoints.

springdoc.api-docs.version

openapi_3_0

String. To Choose OpenAPI 3.0 or OpenAPI 3.1 (using the value OPENAPI_3_1).

springdoc.default-flat-param-object

false

Boolean. To default flatten parameter.

springdoc.default-support-form-data

false

Boolean. To default set parameters to form data when specifying api to accept form data.

springdoc.nullable-request-parameter-enabled

true

Boolean. To default Enable Support for nullable request parameters in Kotlin.

springdoc.show-oauth2-endpoints

false

Boolean. To make spring security oauth2-endpoint visible.

springdoc.api-docs.resolve-extensions-properties

false

Boolean. To enable support of spring property resolver for @ExtensionProperty.

springdoc.enable-default-api-docs

true

Boolean. To enable default OpenAPI endpoint /v3/api-docs.

springdoc.trim-kotlin-indent

false

Boolean. Adjust indentation when parsing the @Operation annotation in Kotlin.

+
+
+

5.2. swagger-ui properties

+
+
    +
  • +

    The support of the swagger-ui properties is available on springdoc-openapi. See Official documentation.

    +
  • +
  • +

    You can use the same swagger-ui properties in the documentation as Spring Boot properties.

    +
  • +
+
+
+ + + + + +
+ + +All these properties should be declared with the following prefix: springdoc.swagger-ui +
+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameter nameDefault ValueDescription

springdoc.swagger-ui.path

/swagger-ui.html

String, For custom path of the swagger-ui HTML documentation.

springdoc.swagger-ui.enabled

true

Boolean. To disable the swagger-ui endpoint (/swagger-ui.html by default).

springdoc.swagger-ui.configUrl

/v3/api-docs/swagger-config

String. URL to fetch external configuration document from.

springdoc.swagger-ui.layout

BaseLayout

String. The name of a component available via the plugin system to use as the top-level layout for Swagger UI.

springdoc.swagger-ui.validatorUrl

By default, Swagger UI does not validate specs. You can use this parameter to set a validator URL, for example for against swagger.io’s online validator.

springdoc.swagger-ui.tryItOutEnabled

true

Boolean. Controls whether the "Try it out" section should be enabled by default.

springdoc.swagger-ui.filter

false

Boolean OR String. If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be Boolean to enable or disable, or a string, in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.

springdoc.swagger-ui.operationsSorter

Function=(a ⇒ a). Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.

springdoc.swagger-ui.tagsSorter

Function=(a ⇒ a). Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function see Array.prototype.sort() to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger UI.

springdoc.swagger-ui.oauth2RedirectUrl

/swagger-ui/oauth2-redirect.html

String. OAuth redirect URL.

springdoc.swagger-ui.displayOperationId

false

Boolean. Controls the display of operationId in operations list. The default is false.

springdoc.swagger-ui.displayRequestDuration

false

Boolean. Controls the display of the request duration (in milliseconds) for "Try it out" requests.

springdoc.swagger-ui.deepLinking

false

Boolean. If set to true, enables deep linking for tags and operations. See the [Deep Linking documentation](swagger.io/docs/open-source-tools/swagger-ui/usage/deep-linking) for more information.

springdoc.swagger-ui.defaultModelsExpandDepth

1

Number. The default expansion depth for models (set to -1 completely hide the models).

springdoc.swagger-ui.defaultModelExpandDepth

1

Number. The default expansion depth for the model on the model-example section.

springdoc.swagger-ui.defaultModelRendering

String=["example"*, "model"]. Controls how the model is shown when the API is first rendered. (The user can always switch the rendering for a given model by clicking the 'Model' and 'Example Value' links.)

springdoc.swagger-ui.docExpansion

String=["list"*, "full", "none"]. Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing).

springdoc.swagger-ui.maxDisplayedTags

Number. If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.

springdoc.swagger-ui.showExtensions

false

Boolean. Controls the display of vendor extension (x-) fields and values for Operations, Parameters, and Schema.

springdoc.swagger-ui.url

String.To configure, the path of a custom OpenAPI file . Will be ignored if urls is used.

springdoc.swagger-ui.showCommonExtensions

false

Boolean. Controls the display of extensions (pattern, maxLength, minLength, maximum, minimum) fields and values for Parameters.

springdoc.swagger-ui.supportedSubmitMethods

Array=[get, put, post, delete, options, head, patch, trace]. List of HTTP methods that have the "Try it out" feature enabled. An empty array disables "Try it out" for all operations. This does not filter the operations from the display.

springdoc.swagger-ui.queryConfigEnabled

false

Boolean. Disabled since v1.6.0. This parameter enables (legacy) overriding configuration parameters via URL search params. See security advisory before enabling this feature.

springdoc.swagger-ui.oauth. additionalQueryStringParams

String. Additional query parameters added to authorizationUrl and tokenUrl.

springdoc.swagger-ui.disable-swagger-default-url

false

Boolean. To disable the swagger-ui default petstore url. (Available since v1.4.1).

springdoc.swagger-ui.urls[0].url

URL. The url of the swagger group, used by Topbar plugin. URLs must be unique among all items in this array, since they’re used as identifiers.

springdoc.swagger-ui.urls[0].name

String. The name of the swagger group, used by Topbar plugin. Names must be unique among all items in this array, since they’re used as identifiers.

springdoc.swagger-ui.urlsPrimaryName

String. The name of the swagger group which will be displayed when Swagger UI loads.

springdoc.swagger-ui.oauth.clientId

String. Default clientId. MUST be a string.

springdoc.swagger-ui.oauth.clientSecret

String. Default clientSecret. Never use this parameter in your production environment. It exposes crucial security information. This feature is intended for dev/test environments only.

springdoc.swagger-ui.oauth.realm

String. realm query parameter (for OAuth 1) added to authorizationUrl and tokenUrl.

springdoc.swagger-ui.oauth.appName

String. OAuth application name, displayed in authorization popup.

springdoc.swagger-ui.oauth.scopeSeparator

String. OAuth scope separator for passing scopes, encoded before calling, default value is a space (encoded value %20).

springdoc.swagger-ui.csrf.enabled

false

Boolean. To enable CSRF support

springdoc.swagger-ui.csrf.use-local-storage

false

Boolean. To get the CSRF token from the Local Storage.

springdoc.swagger-ui.csrf.use-session-storage

false

Boolean. To get the CSRF token from the Session Storage.

springdoc.swagger-ui.csrf.cookie-name

XSRF-TOKEN

String. Optional CSRF, to set the CSRF cookie name.

springdoc.swagger-ui.csrf.header-name

X-XSRF-TOKEN

String. Optional CSRF, to set the CSRF header name.

springdoc.swagger-ui.syntaxHighlight.activated

true

Boolean. Whether syntax highlighting should be activated or not.

springdoc.swagger-ui.syntaxHighlight.theme

agate

String. String=["agate"*, "arta", "monokai", "nord", "obsidian", "tomorrow-night"]. Highlight.js syntax coloring theme to use. (Only these 6 styles are available.)

springdoc.swagger-ui.oauth. useBasicAuthentication WithAccessCodeGrant

false

Boolean. Only activated for the accessCode flow. During the authorization_code request to the tokenUrl, pass the Client Password using the HTTP Basic Authentication scheme (Authorization header with Basic base64encode(client_id + client_secret)).

springdoc.swagger-ui.oauth. usePkceWithAuthorization CodeGrant

false

Boolean.Only applies to authorizatonCode flows. Proof Key for Code Exchange brings enhanced security for OAuth public clients.

springdoc.swagger-ui.persistAuthorization

false

Boolean. If set to true, it persists authorization data and it would not be lost on browser close/refresh

springdoc.swagger-ui.use-root-path

false

Boolean. If set to true, the swagger-ui will be accessible from the application root path directly.

+
+
+
+
+

6. Springdoc-openapi Plugins

+
+
+

6.1. Maven plugin

+
+

The aim of springdoc-openapi-maven-plugin is to generate json and yaml OpenAPI description during build time. +The plugin works during integration-tests phase, and generate the OpenAPI description. +The plugin works in conjunction with spring-boot-maven plugin.

+
+
+

You can test it during the integration tests phase using the maven command:

+
+
+
+
mvn verify
+
+
+
+

In order to use this functionality, you need to add the plugin declaration on the plugins section of your pom.xml:

+
+
+
+
<plugin>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-maven-plugin</artifactId>
+    <version>${spring-boot-maven-plugin.version}</version>
+    <configuration>
+        <jvmArguments>-Dspring.application.admin.enabled=true</jvmArguments>
+    </configuration>
+    <executions>
+        <execution>
+            <goals>
+                <goal>start</goal>
+                <goal>stop</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+<plugin>
+    <groupId>org.springdoc</groupId>
+    <artifactId>springdoc-openapi-maven-plugin</artifactId>
+    <version>1.5</version>
+    <executions>
+        <execution>
+            <id>integration-test</id>
+            <goals>
+                <goal>generate</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

For more custom settings of the springdoc-openapi-maven-plugin, you can consult the plugin documentation:

+
+ +
+
+

6.2. Gradle plugin

+
+

This plugin allows you to generate an OpenAPI 3 specification for a Spring Boot application from a Gradle build.

+
+
+
+
plugins {
+      id("org.springframework.boot") version "2.7.0"
+      id("org.springdoc.openapi-gradle-plugin") version "1.9.0"
+}
+
+
+
+
+

When you add this plugin and its runtime dependency plugins to your build file, the plugin creates the following tasks:

+
+
+
    +
  • +

    forkedSpringBootRun

    +
  • +
  • +

    generateOpenApiDocs

    +
  • +
+
+
+
+
gradle clean generateOpenApiDocs
+
+
+
+

For more custom configuration of springdoc-openapi-gradle-plugin ,you can consult the plugin documentation:

+
+ +
+
+
+ +
+

8. Migrating from SpringFox

+
+
+
    +
  • +

    Remove springfox and swagger 2 dependencies. Add springdoc-openapi-ui dependency instead.

    +
  • +
+
+
+
+
   <dependency>
+      <groupId>org.springdoc</groupId>
+      <artifactId>springdoc-openapi-ui</artifactId>
+      <version>1.8.0</version>
+   </dependency>
+
+
+
+
    +
  • +

    Replace swagger 2 annotations with swagger 3 annotations (it is already included with springdoc-openapi-ui dependency). +Package for swagger 3 annotations is io.swagger.v3.oas.annotations.

    +
    +
      +
    • +

      @Api@Tag

      +
    • +
    • +

      @ApiIgnore@Parameter(hidden = true) or @Operation(hidden = true) or @Hidden

      +
    • +
    • +

      @ApiImplicitParam@Parameter

      +
    • +
    • +

      @ApiImplicitParams@Parameters

      +
    • +
    • +

      @ApiModel@Schema

      +
    • +
    • +

      @ApiModelProperty(allowEmptyValue = true)@Schema(nullable = true)

      +
    • +
    • +

      @ApiModelProperty@Schema

      +
    • +
    • +

      @ApiOperation(value = "foo", notes = "bar")@Operation(summary = "foo", description = "bar")

      +
    • +
    • +

      @ApiParam@Parameter

      +
    • +
    • +

      @ApiResponse(code = 404, message = "foo")@ApiResponse(responseCode = "404", description = "foo")

      +
    • +
    +
    +
  • +
  • +

    If you’re using an object to capture multiple request query params, annotation that method argument with @ParameterObject

    +
  • +
  • +

    This step is optional: Only if you have multiple Docket beans replace them with GroupedOpenApi beans.

    +
  • +
+
+
+

Before:

+
+
+
+
  @Bean
+  public Docket publicApi() {
+      return new Docket(DocumentationType.SWAGGER_2)
+              .select()
+              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public"))
+              .paths(PathSelectors.regex("/public.*"))
+              .build()
+              .groupName("springshop-public")
+              .apiInfo(apiInfo());
+  }
+
+  @Bean
+  public Docket adminApi() {
+      return new Docket(DocumentationType.SWAGGER_2)
+              .select()
+              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin"))
+              .paths(PathSelectors.regex("/admin.*"))
+              .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class))
+              .build()
+              .groupName("springshop-admin")
+              .apiInfo(apiInfo());
+  }
+
+
+
+
+

Now:

+
+
+
+
  @Bean
+  public GroupedOpenApi publicApi() {
+      return GroupedOpenApi.builder()
+              .group("springshop-public")
+              .pathsToMatch("/public/**")
+              .build();
+  }
+  @Bean
+  public GroupedOpenApi adminApi() {
+      return GroupedOpenApi.builder()
+              .group("springshop-admin")
+              .pathsToMatch("/admin/**")
+              .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class))
+              .build();
+  }
+
+
+
+
+

If you have only one Docket — remove it and instead add properties to your application.properties:

+
+
+
+
springdoc.packagesToScan=package1, package2
+springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
    +
  • +

    Add bean of OpenAPI type. See example:

    +
  • +
+
+
+
+
  @Bean
+  public OpenAPI springShopOpenAPI() {
+      return new OpenAPI()
+              .info(new Info().title("SpringShop API")
+              .description("Spring shop sample application")
+              .version("v0.0.1")
+              .license(new License().name("Apache 2.0").url("http://springdoc.org")))
+              .externalDocs(new ExternalDocumentation()
+              .description("SpringShop Wiki Documentation")
+              .url("https://springshop.wiki.github.org/docs"));
+  }
+
+
+
+
+ +
+
+
+
+

9. Other resources

+
+
+

9.1. Additional resources to get started

+ +
+
+

9.2. Dependencies repository

+
+

The springdoc-openapi libraries are hosted on maven central repository. +The artifacts can be viewed accessed at the following locations:

+
+
+

Releases:

+
+ +
+

Snapshots:

+
+ +
+
+
+
+ +
+
+

springdoc-openapi is on Open Collective.

+
+
+

If you ❤️ this project consider becoming a sponsor.

+
+
+

This money is used to cover project expenses and your donation will help the project live and grow successfully.

+
+
+

Thank you to our bronze sponsors!

+
+

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

+
+

10.1. Benefits of being a bronze sponsor

+
+

Bronze sponsors donate $50 per month to the project, and get the following benefits:

+
+
+
    +
  • +

    You will receive a Sponsor badge 🎖!. Visibility on the front page of springdoc.org in the welcome page (about 55,000 views/month on May, 2022).

    +
  • +
  • +

    “Thank you” tweet from `springdoc team'.

    +
  • +
+
+
+
+

10.2. Benefits of being a silver sponsor

+
+

Silver sponsors donate $100 per month to the project, and get the following benefits:

+
+
+
    +
  • +

    Same benefits as bronze sponsors (visibility on main pages, and thank you tweet).

    +
  • +
  • +

    The ability to get support for 2 issues every month, non transferable.

    +
  • +
  • +

    If issues are not created by the end of the month, it is lost

    +
  • +
+
+
+
+

10.3. Benefits of being a gold sponsor

+
+

Gold sponsors donate $500 per month to the project, and get the following benefits:

+
+
+
    +
  • +

    Same benefits as silver sponsors (visibility on main pages, and thank you tweet).

    +
  • +
  • +

    The ability to get support for 10 issues every month, non transferable.

    +
  • +
  • +

    Company logos on all springdoc.org page footers

    +
  • +
  • +

    If issues are not created by the end of the month, the remaining ones are lost.

    +
  • +
+
+
+
+
+
+

11. Special Thanks

+
+
+
    +
  • +

    Thank you to The Spring Team for sharing all relevant resources around Spring projects.

    +
  • +
  • +

    Thanks a lot JetBrains for supporting springdoc-openapi project.

    +
  • +
+
+
+
+JetBrains logo +
+
+
+
+
+

12. F.A.Q

+
+
+

12.1. How can I define multiple OpenAPI definitions in one Spring Boot project?

+
+

You can define your own groups of API based on the combination of: API paths and packages to scan. Each group should have a unique groupName. +The OpenAPI description of this group, will be available by default on:

+
+
+
    +
  • +

    http://server:port/context-path/v3/api-docs/groupName

    +
  • +
+
+
+

To enable the support of multiple OpenAPI definitions, a bean of type GroupedOpenApi needs to be defined.

+
+
+

For the following Group definition(based on package path), the OpenAPI description URL will be : /v3/api-docs/stores

+
+
+
+
@Bean
+public GroupedOpenApi storeOpenApi() {
+   String paths[] = {"/store/**"};
+   return GroupedOpenApi.builder().group("stores").pathsToMatch(paths)
+         .build();
+}
+
+
+
+
+

For the following Group definition (based on package name), the OpenAPI description URL will be: /v3/api-docs/users

+
+
+
+
@Bean
+public GroupedOpenApi userOpenApi() {
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"};
+   return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan)
+         .build();
+}
+
+
+
+
+

For the following Group definition(based on path), the OpenAPI description URL will be: /v3/api-docs/pets

+
+
+
+
@Bean
+public GroupedOpenApi petOpenApi() {
+   String paths[] = {"/pet/**"};
+   return GroupedOpenApi.builder().group("pets").pathsToMatch(paths)
+         .build();
+}
+
+
+
+
+

For the following Group definition (based on package name and path), the OpenAPI description URL will be: /v3/api-docs/groups

+
+
+
+
@Bean
+public GroupedOpenApi groupOpenApi() {
+   String paths[] = {"/v1/**"};
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"};
+   return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
+         .build();
+}
+
+
+
+
+

For more details about the usage, you can have a look at the following sample Test:

+
+ +
+
+

12.2. How can I configure Swagger UI?

+
+
    +
  • +

    The support of the swagger official properties is available on springdoc-openapi. See Official documentation.

    +
  • +
  • +

    You can use the same swagger properties in the documentation as Spring Boot properties.

    +
  • +
+
+
+ + + + + +
+ + +All these properties should be declared with the following prefix: springdoc.swagger-ui +
+
+
+
+

12.3. How can I filter the resources documented in the output specification by the provided group?

+
+
    +
  • +

    You can use the standard swagger-ui property filter.

    +
  • +
+
+
+
+
springdoc.swagger-ui.filter=group-a
+
+
+
+
+

12.4. How can I disable/enable Swagger UI generation based on env variable?

+
+
    +
  • +

    This property helps you disable only the UI.

    +
  • +
+
+
+
+
springdoc.swagger-ui.enabled=false
+
+
+
+
+

12.5. How can I control the default expansion setting for the operations and tags, in the Swagger UI,

+
+
    +
  • +

    You can set this property in your application.yml like so for example:

    +
  • +
+
+
+
+
springdoc.swagger-ui.doc-expansion= none
+
+
+
+
+

12.6. How can I change the layout of the swagger-ui?

+
+
    +
  • +

    For layout options, you can use swagger-ui configuration options. For example:

    +
  • +
+
+
+
+
springdoc.swagger-ui.layout=BaseLayout
+
+
+
+
+

12.7. How can I sort endpoints alphabetically?

+
+
    +
  • +

    You can use the following springdoc-openapi properties:

    +
  • +
+
+
+
+
#For sorting endpoints alphabetically
+springdoc.swagger-ui.operationsSorter=alpha
+#For sorting tags alphabetically
+springdoc.swagger-ui.tagsSorter=alpha
+
+
+
+
+

12.8. How can I disable the try it out button?

+
+
    +
  • +

    You have to set the following property:

    +
  • +
+
+
+
+
springdoc.swagger-ui.supportedSubmitMethods=get, put, post, delete, options, head, patch, trace
+
+
+
+
+

12.9. How can I add Reusable Enums?

+
+
    +
  • +

    You should add @Schema(enumAsRef = true) on your enum.

    +
  • +
+
+
+
+

12.10. How can i apply enumAsRef = true to all enums?

+
+
    +
  • +

    Declare the following property:

    +
  • +
+
+
+
+
static {
+    io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true;
+}
+
+
+
+
+

12.11. How can I explicitly set which paths to filter?

+
+
    +
  • +

    You can set list of paths to include using the following property:

    +
  • +
+
+
+
+
springdoc.pathsToMatch=/v1, /api/balance/**
+
+
+
+
+

12.12. How can I explicitly set which packages to scan?

+
+
    +
  • +

    You can set list of packages to include using the following property:

    +
  • +
+
+
+
+
springdoc.packagesToScan=package1, package2
+
+
+
+
+

12.13. How can I set Swagger properties programmatically?

+
+

These can be set by creating a swaggerUiConfig bean as follows:

+
+
+
+
@Bean
+@Primary
+fun swaggerUiConfig(config: SwaggerUiConfigProperties): SwaggerUiConfigProperties {
+    config.showCommonExtensions = true
+    config.queryConfigEnabled = true
+    return config
+}
+
+
+
+
+
+

12.14. How can I ignore some field of model?

+
+
    +
  • +

    You can use the following annotation on the top of the field that you want to hide:

    +
  • +
  • +

    @Schema(hidden = true)

    +
  • +
+
+
+
+

12.15. How can I ignore @AuthenticationPrincipal parameter from spring-security?

+
+
    +
  • +

    A solution workaround would be to use: @Parameter(hidden = true)

    +
  • +
  • +

    For a project that uses spring-security, you should add the following dependency, in combination with the springdoc-openapi-ui dependency:

    +
  • +
+
+
+
+
<dependency>
+   <groupId>org.springdoc</groupId>
+   <artifactId>springdoc-openapi-security</artifactId>
+   <version>last.version</version>
+</dependency>
+
+
+
+
+

12.16. Is there a Gradle plugin available?

+
+
    +
  • +

    Yes. More details are available, in the gradle plugin section.

    +
  • +
+
+
+
+

12.17. How can I hide a parameter from the documentation?

+
+
    +
  • +

    You can use @Parameter(hidden = true)

    +
  • +
+
+
+
+

12.18. Is @Parameters annotation supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

12.19. Does springdoc-openapi support Jersey?

+
+ +
+
+
+

12.20. Can springdoc-openapi generate API only for @RestController?

+
+
    +
  • +

    @RestController is equivalent to @Controller + @RequestMapping on the type level.

    +
  • +
  • +

    For some legacy apps, we are constrained to still support both.

    +
  • +
  • +

    If you need to hide the @Controller on the type level, in this case, you can use: @Hidden on controller level.

    +
  • +
  • +

    Please note this annotation can be also used to hide some methods from the generated documentation.

    +
  • +
+
+
+
+

12.21. Are the following validation annotations supported : @NotEmpty @NotBlank @PositiveOrZero @NegativeOrZero?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

12.22. How can I map Pageable (spring-data-commons) object to correct URL-Parameter in Swagger UI?

+
+

The support for Pageable of spring-data-commons is available out-of-the box since springdoc-openapi v1.6.0. +For this, you have to combine @ParameterObject annotation with the Pageable type.

+
+
+

Before springdoc-openapi v1.6.0:

+
+
+
    +
  • +

    You can use as well @ParameterObject instead of @PageableAsQueryParam for HTTP GET methods.

    +
  • +
+
+
+
+
static {
+    getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
+            .replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
+}
+
+
+
+
+
    +
  • +

    Another solution, is to configure Pageable manually:

    +
    +
      +
    • +

      you will have to declare the explicit mapping of Pageable fields as Query Params and add the @Parameter(hidden = true) Pageable pageable on your pageable parameter.

      +
    • +
    • +

      You should also, declare the annotation @PageableAsQueryParam provided by springdoc-openapi on the method level, or declare your own if need to define your custom description, defaultValue, …​

      +
    • +
    +
    +
  • +
+
+
+

If you want to disable the support of spring Pageable Type, you can use:

+
+
+
+
springdoc.model-converters.pageable-converter.enabled=false
+
+
+
+ + + + + +
+ + +The property springdoc.model-converters.pageable-converter.enabled is only available since v1.5.11+ +
+
+
+
+

12.23. How can I generate enums in the generated description?

+
+
    +
  • +

    You could add a property allowableValues, to @Parameter. For example:

    +
  • +
+
+
+
+
@GetMapping("/example")
+public Object example(@Parameter(name = "json", schema = @Schema(description = "var 1", type = "string", allowableValues = {"1", "2"}))
+String json) {
+   return null;
+}
+
+
+
+
+
    +
  • +

    or you could override toString on your enum:

    +
  • +
+
+
+
+
@Override
+@JsonValue
+public String toString() {
+   return String.valueOf(action);
+}
+
+
+
+
+
+

12.24. How can I deploy springdoc-openapi-ui behind a reverse proxy?

+
+
    +
  • +

    If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…​) might change along the way. Your application may be running on 10.10.10.10:8080, but HTTP clients should only see example.org.

    +
  • +
  • +

    RFC7239 "Forwarded Headers" defines the Forwarded HTTP header; proxies can use this header to provide information about the original request. You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages. There are also non-standard headers, like X-Forwarded-Host, X-Forwarded-Port, X-Forwarded-Proto, X-Forwarded-Ssl, and X-Forwarded-Prefix.

    +
  • +
  • +

    If the proxy adds the commonly used X-Forwarded-For and X-Forwarded-Proto headers, setting server.forward-headers-strategy to NATIVE is enough to support those. With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior.

    +
  • +
  • +

    You need to make sure the following header is set in your reverse proxy configuration: X-Forwarded-Prefix

    +
  • +
  • +

    For example, using Apache 2, configuration:

    +
  • +
+
+
+
+
RequestHeader set X-Forwarded-Prefix "/custom-path"
+
+
+
+
    +
  • +

    Then, in your Spring Boot application make sure your application handles this header: X-Forwarded-For. There are two ways to achieve this:

    +
  • +
+
+
+
+
server.use-forward-headers=true
+
+
+
+
    +
  • +

    If this is not enough, Spring Framework provides a ForwardedHeaderFilter. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK.

    +
  • +
  • +

    Since Spring Boot 2.2, this is the new property to handle reverse proxy headers:

    +
  • +
+
+
+
+
server.forward-headers-strategy=framework
+
+
+
+
    +
  • +

    And you can add the following bean to your application:

    +
  • +
+
+
+
+
@Bean
+ForwardedHeaderFilter forwardedHeaderFilter() {
+   return new ForwardedHeaderFilter();
+}
+
+
+
+
+
+

12.25. Is @JsonView annotations in Spring MVC APIs supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

12.26. Adding springdoc-openapi-ui dependency breaks my public/index.html welcome page

+
+
    +
  • +

    If you already have static content on your root, and you don’t want it to be overridden by springdoc-openapi-ui configuration, you can just define a custom configuration of the swagger-ui, in order not to override the configuration of your files from in your context-root:

    +
  • +
  • +

    For example use:

    +
  • +
+
+
+
+
springdoc.swagger-ui.path= /swagger-ui/api-docs.html
+
+
+
+
+

12.27. How can I test the Swagger UI?

+ +
+
+

12.28. How can I customise the OpenAPI object?

+
+ +
+
+
+
@Bean
+public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() {
+    return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
+            .forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myGlobalHeader")));
+}
+
+
+
+
+ + + + + +
+ + +This bean OpenApiCustomizer will be applied to the Default OpenAPI only. +
+
+
+

If you need the OpenApiCustomizer to applied to GroupedOpenApi as well, then use GlobalOpenApiCustomizer instead.

+
+
+
+

12.29. How can I return an empty content as response?

+
+
    +
  • +

    It is be possible to handle as return an empty content as response using, one of the following syntaxes:

    +
  • +
  • +

    content = @Content

    +
  • +
  • +

    content = @Content(schema = @Schema(hidden = true))

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
@Operation(summary = "Get thing", responses = {
+      @ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
+      @ApiResponse(responseCode = "404", description = "Not found", content = @Content),
+      @ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) })
+@RequestMapping(path = "/testme", method = RequestMethod.GET)
+ResponseEntity<String> testme() {
+   return ResponseEntity.ok("Hello");
+}
+
+
+
+
+
+

12.30. How are endpoints with multiple consuming media types supported?

+
+
    +
  • +

    An overloaded method on the same class, with the same HTTP Method and path, will have as a result, only one OpenAPI Operation generated.

    +
  • +
  • +

    In addition, it’s recommended to have the @Operation in the level of one of the overloaded methods. Otherwise it might be overridden if it’s declared many times within the same overloaded method.

    +
  • +
+
+
+
+

12.31. How can I get yaml and json (OpenAPI) in compile time?

+
+ +
+
+
+

12.32. What are the ignored types in the documentation?

+
+ +
+
+
+

12.33. How can i disable ignored types:

+
+

If you don’t want to ignore the types Principal, Locale, HttpServletRequest, and others,:

+
+
+
+
SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class)
+
+
+
+
+
+

12.34. How do I add authorization header in requests?

+
+
    +
  • +

    You should add the @SecurityRequirement tags to your protected APIs.

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
@Operation(security = { @SecurityRequirement(name = "bearer-key") })
+
+
+
+
    +
  • +

    And the security definition sample:

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI()
+        .components(new Components()
+        .addSecuritySchemes("bearer-key",
+        new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
+}
+
+
+
+
+
+

12.35. Differentiation to Springfox project

+
+
    +
  • +

    OAS 3 was released in July 2017, and there was no release of springfox to support OAS 3. +springfox covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately.

    +
  • +
  • +

    We decided to move forward and share the library that we already used on our internal projects, with the community.

    +
  • +
  • +

    The biggest difference with springfox, is that we integrate new features not covered by springfox:

    +
  • +
  • +

    The integration between Spring Boot and OpenAPI 3 standard.

    +
  • +
  • +

    We rely on on swagger-annotations and swagger-ui only official libraries.

    +
  • +
  • +

    We support new features on Spring 5, like spring-webflux with annotated and functional style.

    +
  • +
  • +

    We do our best to answer all the questions and address all issues or enhancement requests

    +
  • +
+
+
+
+

12.36. How do I migrate to OpenAPI 3 with springdoc-openapi

+
+
    +
  • +

    There is no relation between springdoc-openapi and springfox.If you want to migrate to OpenAPI 3:

    +
  • +
  • +

    Remove all the dependencies and the related code to springfox

    +
  • +
  • +

    Add springdoc-openapi-ui dependency

    +
  • +
  • +

    If you don’t want to serve the UI from your root path or there is a conflict with an existing configuration, you can just change the following property:

    +
  • +
+
+
+
+
springdoc.swagger-ui.path=/you-path/swagger-ui.html
+
+
+
+
+

12.37. How can I set a global header?

+
+
    +
  • +

    You may have global parameters with Standard OpenAPI description.

    +
  • +
  • +

    If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi, you can use OpenAPI Bean.

    +
  • +
  • +

    You can define common parameters under parameters in the global components section and reference them elsewhere via $ref. You can also define global header parameters.

    +
  • +
  • +

    For this, you can override to OpenAPI Bean, and set the global headers or parameters definition on the components level.

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+ return new OpenAPI()
+        .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
+        .addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
+        .info(new Info()
+        .title("Petstore API")
+        .version(appVersion)
+        .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
+        .termsOfService("http://swagger.io/terms/")
+        .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
+

12.38. Are Callbacks supported?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

12.39. How can I define SecurityScheme?

+
+
    +
  • +

    You can use: @SecurityScheme annotation.

    +
  • +
  • +

    Or you can define it programmatically, by overriding OpenAPI Bean:

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+    return new OpenAPI()
+        .components(new Components().addSecuritySchemes("basicScheme",
+            new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+        .info(new Info().title("SpringShop API").version(appVersion)
+            .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
+

12.40. How can I hide an operation or a controller from documentation?

+
+
    +
  • +

    You can use @io.swagger.v3.oas.annotations.Hidden annotation at @RestController, @RestControllerAdvice and method level

    +
  • +
  • +

    The @Hidden annotation on exception handler methods, is considered when building generic (error) responses from @ControllerAdvice exception handlers.

    +
  • +
  • +

    Or use: @Operation(hidden = true)

    +
  • +
+
+
+
+

12.41. How to configure global security schemes?

+
+
    +
  • +

    For global SecurityScheme, you can add it inside your own OpenAPI definition:

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI().components(new Components()
+        .addSecuritySchemes("basicScheme", new SecurityScheme()
+            .type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API")
+        .version("100")).addTagsItem(new Tag().name("mytag"));
+}
+
+
+
+
+
+

12.42. Can I use spring property with swagger annotations?

+
+
    +
  • +

    The support of spring property resolver for @Info: title * description * version * termsOfService

    +
  • +
  • +

    The support of spring property resolver for @Info.license: name * url

    +
  • +
  • +

    The support of spring property resolver for @Info.contact: name * email * url

    +
  • +
  • +

    The support of spring property resolver for @Operation: description * summary

    +
  • +
  • +

    The support of spring property resolver for @Parameter: description * name

    +
  • +
  • +

    The support of spring property resolver for @ApiResponse: description

    +
  • +
  • +

    Its also possible to declare security URLs for @OAuthFlow: openIdConnectUrl * authorizationUrl * refreshUrl * tokenUrl

    +
  • +
  • +

    The support of spring property resolver for @Schema: name * title * description , by setting springdoc.api-docs.resolve-schema-properties to true

    +
  • +
+
+
+
+

12.43. How is server URL generated?

+
+
    +
  • +

    Generating automatically server URL may be useful, if the documentation is not present.

    +
  • +
  • +

    If the server annotations are present, they will be used instead.

    +
  • +
+
+
+
+

12.44. How can I disable springdoc-openapi cache?

+
+
    +
  • +

    By default, the OpenAPI description is calculated once, and then cached.

    +
  • +
  • +

    Sometimes the same swagger-ui is served behind internal and external proxies. some users want the server URL, to be computed on each http request.

    +
  • +
  • +

    In order to disable springdoc cache, you will have to set the following property:

    +
  • +
+
+
+
+
springdoc.cache.disabled= true
+
+
+
+
+

12.45. How can I expose the mvc api-docs endpoints without using the swagger-ui?

+
+
    +
  • +

    You should use the springdoc-openapi-core dependency only:

    +
  • +
+
+
+
+
<dependency>
+  <groupId>org.springdoc</groupId>
+  <artifactId>springdoc-openapi-webmvc-core</artifactId>
+  <version>latest.version</version>
+</dependency>
+
+
+
+
+

12.46. How can I disable springdoc-openapi endpoints?

+
+
    +
  • +

    Use the following property:

    +
  • +
+
+
+
+
springdoc.api-docs.enabled=false
+
+
+
+
+

12.47. How can I hide Schema of the the response?

+
+
    +
  • +

    To hide the response element, using @Schema annotation, as follows, at operation level:

    +
  • +
+
+
+
+
@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))))
+
+
+
+
    +
  • +

    Or directly at @ApiResponses level:

    +
  • +
+
+
+
+
@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) })
+OR
+@ApiResponse(responseCode = "404", description = "Not found", content = @Content)
+
+
+
+
+

12.48. What is the URL of the swagger-ui, when I set a different context-path?

+
+
    +
  • +

    If you use different context-path:

    +
  • +
+
+
+
+
server.servlet.context-path= /foo
+
+
+
+
    +
  • +

    The swagger-ui will be available on the following URL:

    +
    +
      +
    • +

      http://server:port/foo/swagger-ui.html

      +
    • +
    +
    +
  • +
+
+
+
+

12.49. Can I customize OpenAPI object programmatically?

+
+
    +
  • +

    You can Define your own OpenAPI Bean: If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi, you can use OpenAPI Bean.

    +
  • +
+
+
+
+
@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+    return new OpenAPI()
+        .components(new Components().addSecuritySchemes("basicScheme",
+            new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+        .info(new Info().title("SpringShop API").version(appVersion)
+            .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+
+
+
+
+
    +
  • +

    If you need the definitions to appear within a specific group, and respect the conditions specified on the GroupedOpenApi, you can add OpenApiCustomiser to your GroupedOpenApi definition.

    +
  • +
+
+
+
+
GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomiser(customerGlobalHeaderOpenApiCustomiser())
+                .build()
+
+@Bean
+public OpenApiCustomiser customerGlobalHeaderOpenApiCustomiser() {
+    return openApi -> openApi.path("/foo",
+        new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses()
+            .addApiResponse("default", new ApiResponse().description("")
+                .content(new Content().addMediaType("fatz", new MediaType()))))));
+}
+
+
+
+
+
+

12.50. Where can I find the source code of the demo applications?

+
+ +
+
+
+

12.51. Does this library supports annotations from interfaces?

+
+
    +
  • +

    Yes

    +
  • +
+
+
+
+

12.52. What is the list of the excluded parameter types?

+ +
+
+

12.53. Is file upload supported?

+
+
    +
  • +

    The library supports the main file types: MultipartFile, @RequestPart, FilePart

    +
  • +
+
+
+
+

12.54. Can I use @Parameter inside @Operation annotation?

+
+
    +
  • +

    Yes, it’s supported

    +
  • +
+
+
+
+

12.55. Why my parameter is marked as required?

+
+
    +
  • +

    Any @GetMapping parameters is marked as required, even if @RequestParam is missing.

    +
  • +
  • +

    You can add @Parameter(required=false) annotation if you need different behaviour.

    +
  • +
  • +

    Query parameters with defaultValue specified are marked as required.

    +
  • +
+
+
+
+

12.56. How are overloaded methods with the same endpoints, but with different parameters

+
+
    +
  • +

    springdoc-openapi renders these methods as a single endpoint. It detects the overloaded endpoints, and generates parameters.schema.oneOf.

    +
  • +
+
+
+
+

12.57. What is a proper way to set up Swagger UI to use provided spec.yml?

+
+
    +
  • +

    With this property, all the springdoc-openapi auto-configuration beans are disabled:

    +
  • +
+
+
+
+
springdoc.api-docs.enabled=false
+
+
+
+
    +
  • +

    Then enable the minimal Beans configuration, by adding this Bean:

    +
  • +
+
+
+
+
@Bean
+SpringDocConfiguration springDocConfiguration(){
+   return new SpringDocConfiguration();
+}
+
+@Bean
+SpringDocConfigProperties springDocConfigProperties() {
+   return new SpringDocConfigProperties();
+}
+
+@Bean
+ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){
+    return new ObjectMapperProvider(springDocConfigProperties);
+}
+
+
+
+
+
    +
  • +

    Then configure, the path of your custom UI yaml file.

    +
  • +
+
+
+
+
springdoc.swagger-ui.url=/api-docs.yaml
+
+
+
+
+

12.58. Is there a way to send authorization header through the @Parameter tag?

+
+ +
+
+
+

12.59. My Rest Controller using @Controller annotation is ignored?

+
+
    +
  • +

    This is the default behaviour if your @Controller doesn’t have annotation @ResponseBody

    +
  • +
  • +

    You can change your controllers to @RestControllers. Or add @ResponseBody + @Controller.

    +
  • +
  • +

    If its not possible, you can configure springdoc to scan you additional controller using SpringDocUtils. For example:

    +
  • +
+
+
+
+
static {
+   SpringDocUtils.getConfig().addRestControllers(HelloController.class);
+}
+
+
+
+
+
+

12.60. How can I define groups using application.yml?

+
+
    +
  • +

    You can load groups dynamically using spring-boot configuration files.

    +
  • +
  • +

    Note that, for this usage, you don’t have to declare the GroupedOpenApi Bean.

    +
  • +
  • +

    You need to declare the following properties, under the prefix springdoc.group-configs.

    +
  • +
  • +

    For example:

    +
  • +
+
+
+
+
springdoc.group-configs[0].group=users
+springdoc.group-configs[0].paths-to-match=/user/**
+springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api
+
+
+
+ +
+
+
+

12.61. How can I extract fields from parameter object?

+
+
    +
  • +

    You can use springdoc annotation @ParameterObject.

    +
  • +
  • +

    Request parameter annotated with @ParameterObject will help adding each field of the parameter as a separate request parameter.

    +
  • +
  • +

    This is compatible with Spring MVC request parameters mapping to POJO object.

    +
  • +
  • +

    This annotation does not support nested parameter objects.

    +
  • +
  • +

    POJO object must contain getters for fields with mandatory prefix get. Otherwise, the swagger documentation will not show the fields of the annotated entity.

    +
  • +
+
+
+
+

12.62. How to Integrate Open API 3 with Spring project (not Spring Boot)?

+
+

When your application is using spring without (spring-boot), you need to add beans and auto-configuration that are natively provided in spring-boot.

+
+
+

For example, lets assume you want load the swagger-ui in spring-mvc application:

+
+
+
    +
  • +

    You mainly, need to add the springdoc-openapi module

    +
  • +
+
+
+
+
<dependency>
+   <groupId>org.springdoc</groupId>
+   <artifactId>springdoc-openapi-ui</artifactId>
+   <version>last.version</version>
+</dependency>
+
+
+
+
    +
  • +

    If you don’t have the spring-boot and spring-boot-autoconfigure dependencies, you need to add them. And pay attention to the compatibility matrix, between you spring.version and spring-boot.version. For example, in this case (spring.version=5.1.12.RELEASE):

    +
  • +
+
+
+
+
<dependency>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot</artifactId>
+    <version>2.1.11.RELEASE</version>
+</dependency>
+<dependency>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-autoconfigure</artifactId>
+    <version>2.1.11.RELEASE</version>
+</dependency>
+
+
+
+
    +
  • +

    Scan for the springdoc-openapi 'auto-configuration classes that spring-boot automatically loads for you.

    +
  • +
  • +

    Depending on your module, you can find them on the file: spring.factories of each springdoc-openapi module.

    +
  • +
+
+
+
+
@EnableWebMvc
+public class AppInitializer implements WebApplicationInitializer {
+
+   @Override
+   public void onStartup(ServletContext servletContext) throws ServletException {
+      WebApplicationContext context = getContext();
+      servletContext.addListener(new ContextLoaderListener(context));
+      ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet",
+            new DispatcherServlet(context));
+      dispatcher.setLoadOnStartup(1);
+      dispatcher.addMapping("/*");
+   }
+
+   private AnnotationConfigWebApplicationContext getContext() {
+      AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+      context.scan("rest");
+      context.register(this.getClass(), org.springdoc.webmvc.ui.SwaggerConfig.class,
+            org.springdoc.core.SwaggerUiConfigProperties.class, org.springdoc.core.SwaggerUiOAuthProperties.class,
+            org.springdoc.webmvc.core.SpringDocWebMvcConfiguration.class,
+            org.springdoc.webmvc.core.MultipleOpenApiSupportConfiguration.class,
+            org.springdoc.core.SpringDocConfiguration.class, org.springdoc.core.SpringDocConfigProperties.class,
+            org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.class);
+
+      return context;
+   }
+}
+
+
+
+
+
    +
  • +

    Depending on your module, you can find them on the file: spring.factories of each springdoc-openapi module.

    +
  • +
  • +

    For groups usage make sure your GroupedOpenApi Beans are scanned.

    +
  • +
  • +

    If additionally, you are using custom context path: /my-servlet-path. Make sure you declare the following property:

    +
  • +
+
+
+
+
spring.mvc.servlet.path=/my-servlet-path
+
+
+
+
+

12.63. How can I use the last springdoc-openapi SNAPSHOT ?

+
+
    +
  • +

    For testing purposes only, you can test temporarily using the last springdoc-openapi SNAPSHOT

    +
  • +
  • +

    To achieve that, configure your pom.xml file with the following <repositories> section:

    +
  • +
+
+
+
+
    <repositories>
+      <repository>
+        <name>Central Portal Snapshots</name>
+        <id>central-portal-snapshots</id>
+        <url>https://central.sonatype.com/repository/maven-snapshots/</url>
+        <releases>
+          <enabled>false</enabled>
+        </releases>
+        <snapshots>
+          <enabled>true</enabled>
+        </snapshots>
+      </repository>
+    </repositories>
+
+
+
+
+

12.64. How can I use enable springdoc-openapi MonetaryAmount support?

+
+
    +
  • +

    If an application wants to enable the springdoc-openapi support, it declares:

    +
  • +
+
+
+
+
SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
+
+
+
+
+
    +
  • +

    Another solution, without using springdoc-openapi MonetaryAmount, would be:

    +
  • +
+
+
+
+
SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema()
+            .addProperties("amount", new NumberSchema()).example(99.96)
+            .addProperties("currency", new StringSchema().example("USD")));
+
+
+
+
+
+

12.65. How can i aggregate external endpoints (exposing OPENAPI 3 spec) inside one single application?

+
+

The properties springdoc.swagger-ui.urls.*, are suitable to configure external (/v3/api-docs url). +For example, if you want to aggregate all the endpoints of other services, inside one single application. +IMPORTANT: Don’t forget that CORS needs to be enabled as well.

+
+
+
+

12.66. How can use custom json/yml file instead of generated one?

+
+

If your file open-api.json, contains the OpenAPI documentation in OpenAPI 3 format. +Then simply declare: The file name can be anything you want, from the moment your declaration is consistent yaml or json OpenAPI Spec.

+
+
+
+
   springdoc.swagger-ui.url=/open-api.json
+
+
+
+

Then the file open-api.json, should be located in: src/main/resources/static +No additional configuration is needed.

+
+
+
+

12.67. How can i enable CSRF support?

+
+

If you are using standard headers. (For example, using spring-security headers) +If the CSRF Token is required, swagger-ui automatically sends the new XSRF-TOKEN during each HTTP REQUEST.

+
+
+

If your XSRF-TOKEN isn’t standards-based, you can use a requestInterceptor to manually capture and attach the latest xsrf token to requests programmatically via spring resource transformer:

+
+ +
+

Starting from release v1.4.4 of springdoc-openapi, a new property is added to enable CSRF support, while using standard header names:

+
+
+
+
springdoc.swagger-ui.csrf.enabled=true
+
+
+
+
+

12.68. How can i disable the default swagger petstore URL?

+
+

You can use the following property:

+
+
+
+
springdoc.swagger-ui.disable-swagger-default-url=true
+
+
+
+
+

12.69. Is @PageableDefault supported, to enhance the OpenAPI 3 documentation?

+
+

Yes, you can use it in conjunction with @ParameterObject annotation. +Also, the spring-boot spring.data.web. and spring.data.rest.default. properties are supported since v1.4.5

+
+
+
+

12.70. How can I make spring security login-endpoint visible?

+
+

You can use the following property:

+
+
+
+
springdoc.show-login-endpoint=true
+
+
+
+
+

12.71. How can I show schema definitions even if the schema is not referenced?

+
+

You can use the following property:

+
+
+
+
springdoc.remove-broken-reference-definitions=false
+
+
+
+
+

12.72. How to override @Deprecated?

+
+

The whole idea of springdoc-openapi is to get your documentation the closest to the code, with minimal code changes. +If the code contains @Deprecated, sprindoc-openapi will consider its schema as Deprecated as well. +If you want to declare a field on swagger as non deprecated, even with the java code, the field contains @Depreacted, +You can use the following property that is available since release v1.4.3:

+
+
+
+
springdoc.model-converters.deprecating-converter.enabled=false
+
+
+
+
+

12.73. How can i display a method that returns ModelAndView?

+
+

You can use the following property:

+
+
+
+
springdoc.model-and-view-allowed=true
+
+
+
+
+

12.74. How can i have pretty-printed output of the OpenApi specification?

+
+

You can use the following property:

+
+
+
+
springdoc.writer-with-default-pretty-printer=true
+
+
+
+
+

12.75. How can i define different schemas for the same class?

+
+

Complex objects are always resolved as a reference to a schema defined in components. +For example, let’s consider a Instance class with an workAddress and homeAddress attribute of type Address:

+
+
+
+
public class PersonDTO {
+
+    @JsonProperty
+    private String email;
+
+    @JsonProperty
+    private String firstName;
+
+    @JsonProperty
+    private String lastName;
+
+    @Schema(ref = "WorkAddressSchema")
+    @JsonProperty
+    private Address workAddress;
+
+    @Schema(ref = "HomeAddressSchema")
+    @JsonProperty
+    private Address homeAddress;
+
+}
+
+public class Address {
+
+    @JsonProperty
+    private String addressName;
+
+}
+
+
+
+
+

If you want to define two different schemas for this class, you can set up 2 different schemas as follow:

+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI().components(new Components()
+        .addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address"))
+        .addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address")));
+}
+
+private Schema getSchemaWithDifferentDescription(Class className, String description) {
+    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+        .resolveAsResolvedSchema(
+            new AnnotatedType(className).resolveAsRef(false));
+    return resolvedSchema.schema.description(description);
+}
+
+
+
+
+
+

12.76. How can i define different description for a class attribute depending on usage?

+
+

For example, let’s consider a Instance class with an email attribute:

+
+
+
+
public class PersonDTO {
+
+    @JsonProperty
+    private String email;
+
+    @JsonProperty
+    private String firstName;
+
+    @JsonProperty
+    private String lastName;
+
+
+}
+
+
+
+
+

If you want to define two different description for the email, you can set up 2 different schemas as follow:

+
+
+
+
@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI().components(new Components()
+        .addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email"))
+        .addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email")));
+}
+
+private Schema getFieldSchemaWithDifferentDescription(Class className, String description) {
+    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+        .resolveAsResolvedSchema(
+            new AnnotatedType(className).resolveAsRef(false));
+    return resolvedSchema.schema.addProperties("email", new StringSchema().description(description));
+}
+
+
+
+
+
+

12.77. Customizing swagger static resources

+
+

You can customize swagger documentation static resources located in META-INF/resources/webjars/swagger-ui/{swagger.version}/. The list of resources includes:

+
+
+
    +
  • +

    index.html

    +
  • +
  • +

    swagger-ui-bundle.js

    +
  • +
  • +

    swagger-ui.css

    +
  • +
  • +

    swagger-ui-standalone-preset.js

    +
  • +
  • +

    swagger-ui.css.map

    +
  • +
  • +

    swagger-ui-bundle.js.map

    +
  • +
  • +

    swagger-ui-standalone-preset.js.map

    +
  • +
  • +

    favicon-32x32.png

    +
  • +
+
+
+

To do this, you need to extend the implementation of SwaggerIndexPageTransformer

+
+
+
+
public class SwaggerCodeBlockTransformer
+       extends SwaggerIndexPageTransformer {
+  // < constructor >
+  @Override
+  public Resource transform(HttpServletRequest request,
+                            Resource resource,
+                            ResourceTransformerChain transformer)
+                            throws IOException {
+      if (resource.toString().contains("swagger-ui.css")) {
+          final InputStream is = resource.getInputStream();
+          final InputStreamReader isr = new InputStreamReader(is);
+          try (BufferedReader br = new BufferedReader(isr)) {
+              final String css = br.lines().collect(Collectors.joining());
+              final byte[] transformedContent = css.replace("old", "new").getBytes();
+              return  new TransformedResource(resource, transformedContent);
+          } // AutoCloseable br > isr > is
+      }
+      return super.transform(request, resource, transformer);
+  }
+
+}
+
+
+
+
+

Next, add transformer @Bean to your @Configuration

+
+
+
+
@Configuration
+public class OpenApiConfig {
+    @Bean
+    public SwaggerIndexTransformer swaggerIndexTransformer(
+            SwaggerUiConfigProperties a,
+            SwaggerUiOAuthProperties b,
+            SwaggerUiConfigParameters c,
+            SwaggerWelcomeCommon d) {
+        return new SwaggerCodeBlockTransformer(a, b, c, d);
+    }
+}
+
+
+
+
+

Illustrative example

+
+
+
+Illustrative example +
+
+
+
+

12.78. What is the compatibility matrix of springdoc-openapi with spring-boot ?

+
+

springdoc-openapi is compatible with spring-boot 1 and spring-boot 2.

+
+
+

In general, you should only pick the last stable version as per today 1.8.0.

+
+
+

More precisely, this the exhaustive list of spring-boot versions against which springdoc-openapi has been built:

+
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
spring-boot VersionsMinimum springdoc-openapi Versions

3.0.x

2.0.x+

2.7.x, 1.5.x

1.6.11+

2.6.x, 1.5.x

1.6.0+

2.5.x, 1.5.x

1.5.9+

2.4.x, 1.5.x

1.5.0+

2.3.x, 1.5.x

1.4.0+

2.2.x, 1.5.x

1.2.1+

2.0.x, 1.5.x

1.0.0+

+
+
+

12.79. Why am i getting an error: Swagger UI unable to render definition, when overriding the default spring registered HttpMessageConverter?

+
+

When overriding the default spring-boot registered HttpMessageConverter, you should have ByteArrayHttpMessageConverter registered as well to have proper springdoc-openapi support.

+
+
+
+
    converters.add(new ByteArrayHttpMessageConverter());
+    converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder.build()));
+
+
+
+
+ + + + + +
+ + +Order is very important, when registering HttpMessageConverters. +
+
+
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/v1/intro.html b/docs/v1/intro.html new file mode 100644 index 0000000..5f657ae --- /dev/null +++ b/docs/v1/intro.html @@ -0,0 +1,91 @@ + + + + + + + +Introduction + + + + + + +
+
+
+ +
+
+

Introduction

+
+
+

springdoc-openapi java library helps to automate the generation of API documentation using spring boot projects. +springdoc-openapi works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations.

+
+
+

Automatically generates documentation in JSON/YAML and HTML format APIs. +This documentation can be completed by comments using swagger-api annotations.

+
+
+

This library supports:

+
+
+
    +
  • +

    OpenAPI 3

    +
  • +
  • +

    Spring-boot (v1, v2 and v3)

    +
  • +
  • +

    JSR-303, specifically for @NotNull, @Min, @Max, and @Size.

    +
  • +
  • +

    Swagger-ui

    +
  • +
  • +

    OAuth 2

    +
  • +
  • +

    GraalVM native images

    +
  • +
+
+
+

The following video introduces the Library:

+
+
+
+spring.io conference +
+
+
+

This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal).

+
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/docs/v1/js/setup.js b/docs/v1/js/setup.js new file mode 100755 index 0000000..ae5b1b7 --- /dev/null +++ b/docs/v1/js/setup.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/docs/v1/js/setup.js.map b/docs/v1/js/setup.js.map new file mode 100755 index 0000000..2971105 --- /dev/null +++ b/docs/v1/js/setup.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["setup/src/main/js/setup/layout.js","setup/node_modules/browser-pack-flat/_prelude","setup/node_modules/lodash/_baseDelay.js","setup/switchtheme.js","setup/node_modules/lodash/identity.js","setup/node_modules/lodash/_apply.js","setup/node_modules/lodash/_overRest.js","setup/node_modules/lodash/constant.js","setup/node_modules/lodash/_freeGlobal.js","setup/node_modules/lodash/_root.js","setup/node_modules/lodash/_Symbol.js","setup/node_modules/lodash/_getRawTag.js","setup/node_modules/lodash/_objectToString.js","setup/node_modules/lodash/_baseGetTag.js","setup/node_modules/lodash/isObject.js","setup/node_modules/lodash/isFunction.js","setup/node_modules/lodash/_isMasked.js","setup/node_modules/lodash/_coreJsData.js","setup/node_modules/lodash/_toSource.js","setup/node_modules/lodash/_baseIsNative.js","setup/node_modules/lodash/_getValue.js","setup/node_modules/lodash/_getNative.js","setup/node_modules/lodash/_defineProperty.js","setup/node_modules/lodash/_baseSetToString.js","setup/node_modules/lodash/_shortOut.js","setup/node_modules/lodash/_setToString.js","setup/node_modules/lodash/_baseRest.js","setup/node_modules/lodash/_trimmedEndIndex.js","setup/node_modules/lodash/_baseTrim.js","setup/node_modules/lodash/isObjectLike.js","setup/node_modules/lodash/isSymbol.js","setup/node_modules/lodash/toNumber.js","setup/node_modules/lodash/delay.js","setup/src/main/js/setup/switchtheme.js","setup/node_modules/browser-pack-flat/_postlude"],"names":["document","getElementsByTagName","classList","add","_$baseDelay_3","func","wait","args","TypeError","setTimeout","apply","undefined","_$identity_25","value","_$apply_2","thisArg","length","call","nativeMax","Math","max","_$overRest_17","start","transform","arguments","index","array","Array","otherArgs","this","_$constant_23","_$freeGlobal_11","global","freeGlobal","Object","self","window","freeSelf","_$root_18","Function","_$Symbol_1","Symbol","objectProto","prototype","hasOwnProperty","nativeObjectToString","toString","symToStringTag","toStringTag","_$getRawTag_13","isOwn","tag","unmasked","e","result","__nativeObjectToString_16","_$objectToString_16","__symToStringTag_4","_$baseGetTag_4","_$isObject_27","type","uid","_$isFunction_26","_$coreJsData_9","maskSrcKey","exec","keys","IE_PROTO","_$isMasked_15","funcToString","_$toSource_21","reIsHostCtor","__funcProto_5","__objectProto_5","__funcToString_5","__hasOwnProperty_5","reIsNative","RegExp","replace","_$baseIsNative_5","test","_$getValue_14","object","key","_$getNative_12","_$defineProperty_10","_$baseSetToString_7","string","configurable","enumerable","writable","nativeNow","Date","now","_$shortOut_20","count","lastCalled","stamp","remaining","_$setToString_19","reWhitespace","_$trimmedEndIndex_22","charAt","reTrimStart","_$baseTrim_8","slice","_$isObjectLike_28","_$isSymbol_29","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","parseInt","_$toNumber_30","other","valueOf","isBinary","_$delay_24","_$baseRest_6","localStorage","htmlElement","documentElement","prefersDarkColorScheme","matchMedia","isInitialThemeDark","theme","getItem","matches","onThemeChange","checked","saveTheme","remove","setItem","addEventListener","toggleCheckboxElement","querySelector","bind"],"mappings":"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","file":"setup.js","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(function () {\n \"use strict\";\n document.getElementsByTagName(\"html\")[0].classList.add(\"js\");\n})();\n","(function(){\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\nfunction baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n}\n\nmodule.exports = baseDelay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n const localStorage = window.localStorage;\n const htmlElement = document.documentElement;\n const prefersDarkColorScheme = window.matchMedia(\n \"(prefers-color-scheme: dark)\"\n );\n\n swithInitialTheme();\n window.addEventListener(\"load\", onWindowLoad);\n\n function swithInitialTheme() {\n if (isInitialThemeDark()) {\n htmlElement.classList.add(\"dark-theme\");\n }\n }\n\n function onWindowLoad() {\n const toggleCheckboxElement = document.querySelector(\n \"#switch-theme-checkbox\"\n );\n toggleCheckboxElement.checked = isInitialThemeDark();\n toggleCheckboxElement.addEventListener(\n \"change\",\n onThemeChange.bind(toggleCheckboxElement)\n );\n }\n\n function isInitialThemeDark() {\n const theme = loadTheme();\n return theme ? theme === \"dark\" : prefersDarkColorScheme.matches;\n }\n\n function onThemeChange() {\n if (this.checked) {\n delay(function () {\n htmlElement.classList.add(\"dark-theme\");\n }, 100);\n saveTheme(\"dark\");\n } else {\n delay(function () {\n htmlElement.classList.remove(\"dark-theme\");\n }, 100);\n saveTheme(\"light\");\n }\n }\n\n function saveTheme(theme) {\n if (localStorage) {\n localStorage.setItem(\"theme\", theme);\n }\n }\n\n function loadTheme() {\n return localStorage !== null ? localStorage.getItem(\"theme\") : null;\n }\n})();\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n","var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","var baseDelay = require('./_baseDelay'),\n baseRest = require('./_baseRest'),\n toNumber = require('./toNumber');\n\n/**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\nvar delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n});\n\nmodule.exports = delay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n const localStorage = window.localStorage;\n const htmlElement = document.documentElement;\n const prefersDarkColorScheme = window.matchMedia(\n \"(prefers-color-scheme: dark)\"\n );\n\n swithInitialTheme();\n window.addEventListener(\"load\", onWindowLoad);\n\n function swithInitialTheme() {\n if (isInitialThemeDark()) {\n htmlElement.classList.add(\"dark-theme\");\n }\n }\n\n function onWindowLoad() {\n const toggleCheckboxElement = document.querySelector(\n \"#switch-theme-checkbox\"\n );\n toggleCheckboxElement.checked = isInitialThemeDark();\n toggleCheckboxElement.addEventListener(\n \"change\",\n onThemeChange.bind(toggleCheckboxElement)\n );\n }\n\n function isInitialThemeDark() {\n const theme = loadTheme();\n return theme ? theme === \"dark\" : prefersDarkColorScheme.matches;\n }\n\n function onThemeChange() {\n if (this.checked) {\n delay(function () {\n htmlElement.classList.add(\"dark-theme\");\n }, 100);\n saveTheme(\"dark\");\n } else {\n delay(function () {\n htmlElement.classList.remove(\"dark-theme\");\n }, 100);\n saveTheme(\"light\");\n }\n }\n\n function saveTheme(theme) {\n if (localStorage) {\n localStorage.setItem(\"theme\", theme);\n }\n }\n\n function loadTheme() {\n return localStorage !== null ? localStorage.getItem(\"theme\") : null;\n }\n})();\n","\n}());"]} \ No newline at end of file diff --git a/docs/v1/js/site.js b/docs/v1/js/site.js new file mode 100755 index 0000000..24a40b4 --- /dev/null +++ b/docs/v1/js/site.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?"Expand 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 s(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 r=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(!r(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){r(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+)?)",p="\\b(0b[01]+)",f={begin:"\\\\[\\s\\S]",relevance:0},_={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[f]},E={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[f]},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=s({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("#","$"),M={className:"number",begin:m,relevance:0},O={className:"number",begin:h,relevance:0},k={className:"number",begin:p,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},S={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[f,{begin:/\[/,end:/\]/,relevance:0,contains:[f]}]}]},A={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:p,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.*/)),s({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:f,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:M,C_NUMBER_MODE:O,BINARY_NUMBER_MODE:k,CSS_NUMBER_MODE:R,REGEXP_MODE:S,TITLE_MODE:A,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=s(e.classNameAliases||{}),function n(a,r){const o=a;if(a.isCompiled)return o;[I].forEach((e=>e(a,r))),e.compilerExtensions.forEach((e=>e(a,r))),a.__beforeBegin=null,[B,$,j].forEach((e=>e(a,r))),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),r&&(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&&r.terminatorEnd&&(o.terminatorEnd+=(a.end?"|":"")+r.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 s(e,{variants:null},n)})));if(e.cachedVariants)return e.cachedVariants;if(H(e))return s(e,{starts:e.starts?s(e.starts):null});if(Object.isFrozen(e))return s(e);return e}("self"===e?a:e)}))),a.contains.forEach((function(e){n(e,o)})),a.starts&&n(a.starts,r),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=F(e);if(!a.length)return;const s=document.createElement("div");s.innerHTML=n.value,n.value=function(e,n,t){let a=0,s="";const r=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function c(e){s+=""}function g(e){("start"===e.event?l:c)(e.node)}for(;e.length||n.length;){let n=o();if(s+=i(t.substring(a,n[0].offset)),a=n[0].offset,n===e){r.reverse().forEach(c);do{g(n.splice(0,1)[0]),n=o()}while(n===e&&n.length&&n[0].offset===a);r.reverse().forEach(l)}else"start"===n[0].event?r.push(n[0].node):r.pop(),g(n.splice(0,1)[0])}return s+i(t.substr(a))}(a,F(s),t)}};function q(e){return e.nodeName.toLowerCase()}function F(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),q(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=s,ee=Symbol("nomatch");var ne=function(e){const t=Object.create(null),i=Object.create(null),s=[];let r=!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="",s="";"object"==typeof n?(i=e,t=n.ignoreIllegals,s=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"),s=e,i=n);const r={code:i,language:s};O("before:highlight",r);const o=r.result?r.result:m(r.language,r.code,t,a);return o.code=r.code,O("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!=M.subLanguage?function(){if(""===R)return;let e=null;if("string"==typeof M.subLanguage){if(!t[M.subLanguage])return void k.addText(R);e=m(M.subLanguage,R,!0,O[M.subLanguage]),O[M.subLanguage]=e.top}else e=h(R,M.subLanguage.length?M.subLanguage:null);M.relevance>0&&(S+=e.relevance),k.addSublanguage(e.emitter,e.language)}():function(){if(!M.keywords)return void k.addText(R);let e=0;M.keywordPatternRe.lastIndex=0;let n=M.keywordPatternRe.exec(R),t="";for(;n;){t+=R.substring(e,n.index);const a=c(M,n);if(a){const[e,i]=a;if(k.addText(t),t="",S+=i,e.startsWith("_"))t+=n[0];else{const t=N.classNameAliases[e]||e;k.addKeyword(n[0],t)}}else t+=n[0];e=M.keywordPatternRe.lastIndex,n=M.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),M=Object.create(e,{parent:{value:M}}),M}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 p(e){return 0===M.matcher.regexIndex?(R+=e[0],1):(C=!0,0)}function f(e){const n=e[0],t=e.rule,i=new a(t),s=[t.__beforeBegin,t["on:begin"]];for(const t of s)if(t&&(t(e,i),i.isMatchIgnored))return p(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(M,e,a);if(!i)return ee;const s=M;s.skip?R+=t:(s.returnEnd||s.excludeEnd||(R+=t),g(),s.excludeEnd&&(R=t));do{M.className&&k.closeNode(),M.skip||M.subLanguage||(S+=M.relevance),M=M.parent}while(M!==i.parent);return i.starts&&(i.endSameAsBegin&&(i.starts.endRe=i.endRe),u(i.starts)),s.returnEnd?0:t.length}let E={};function v(t,a){const s=a&&a[0];if(R+=t,null==s)return g(),0;if("begin"===E.type&&"end"===a.type&&E.index===a.index&&""===s){if(R+=n.slice(a.index,a.index+1),!r){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 f(a);if("illegal"===a.type&&!i){const e=new Error('Illegal lexeme "'+s+'" for mode "'+(M.className||"")+'"');throw e.mode=M,e}if("end"===a.type){const e=_(a);if(e!==ee)return e}if("illegal"===a.type&&""===s)return 1;if(T>1e5&&T>3*a.index){throw new Error("potential infinite loop, way more iterations than matches")}return R+=s,s.length}const N=w(e);if(!N)throw Q(l.replace("{}",e)),new Error('Unknown language: "'+e+'"');const y=K(N,{plugins:s});let x="",M=o||y;const O={},k=new d.__emitter(d);!function(){const e=[];for(let n=M;n!==N;n=n.parent)n.className&&e.unshift(n.className);e.forEach((e=>k.openNode(e)))}();let R="",S=0,A=0,T=0,C=!1;try{for(M.matcher.considerAll();;){T++,C?C=!1:M.matcher.considerAll(),M.matcher.lastIndex=A;const e=M.matcher.exec(n);if(!e)break;const t=v(n.substring(A,e.index),e);A=e.index+t}return v(n.substr(A)),k.closeAllNodes(),k.finalize(),x=k.toHTML(),{relevance:Math.floor(S),value:x,language:e,illegal:!1,emitter:k,top:M}}catch(t){if(t.message&&t.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:t.message,context:n.slice(A-100,A+100),mode:t.mode},sofar:x,relevance:0,value:J(n),emitter:k};if(r)return{illegal:!1,relevance:0,value:J(n),emitter:k,language:e,top:M,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(M).map((n=>m(n,e,!1)));i.unshift(a);const s=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})),[r,o]=s,l=r;return l.second_best=o,l}const p={"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,"
"))}},f=/^(<[^>]+>|\t)+/gm,_={"after:highlightElement":({result:e})=>{d.tabReplace&&(e.value=e.value.replace(f,(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;O("before:highlightElement",{el:e,language:t}),n=e;const a=n.textContent,s=t?b(a,{language:t,ignoreIllegals:!0}):h(a);O("after:highlightElement",{el:e,result:s,text:a}),e.innerHTML=s.value,function(e,n,t){const a=n?i[n]:t;e.classList.add("hljs"),a&&e.classList.add(a)}(e,t,s.language),e.result={language:s.language,re:s.relevance,relavance:s.relevance},s.second_best&&(e.second_best={language:s.second_best.language,re:s.second_best.relevance,relavance:s.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 M(e){const n=w(e);return n&&!n.disableAutodetect}function O(e,n){const t=e;s.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)),!r)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:M,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),s.push(e)},vuePlugin:Z(e).VuePlugin}),e.debugMode=function(){r=!1},e.safeMode=function(){r=!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(p),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 se=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"})]}},s={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n,a]};a.contains.push(s);const r={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,r,e.HASH_COMMENT_MODE,i,s,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},n]}};const re=["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("+re.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 _e(e,n={}){return n.variants=e,n}var Ee=function(e){const n="[A-Za-z0-9_$]+",t=_e([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=_e([e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]),s=_e([{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,s,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,s,a,i,"self"]},{className:"symbol",begin:"^[ \t]*"+fe(n+":"),excludeBegin:!0,end:n+":",relevance:0}],illegal:/#|<\//}};function ve(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ne=function(e){const n="HTTP/(2|1\\.[01])",t={className:"attribute",begin:ve("^",/[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})]}},ye="\\.([0-9](_*[0-9])*)",we="[0-9a-fA-F](_*[0-9a-fA-F])*",xe={className:"number",variants:[{begin:`(\\b([0-9](_*[0-9])*)((${ye})|\\.)?|(${ye}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:`\\b([0-9](_*[0-9])*)((${ye})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${ye})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{begin:`\\b0[xX]((${we})\\.?|(${we})?\\.(${we}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${we})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};var Me=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=xe;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$_]*",ke=["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"],Re=["true","false","null","undefined","NaN","Infinity"],Se=[].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 Te("(?=",e,")")}function Te(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ce=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:s,contains:p}]}]},{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:s,contains:["self",e.inherit(e.TITLE_MODE,{begin:n}),f],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[f,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",f]},{begin:"(get|set)\\s+(?="+n+"\\()",end:/\{/,keywords:"get set",contains:[e.inherit(e.TITLE_MODE,{begin:n}),{begin:/\(\)/},f]},{begin:/\$[(.]/}]}};var De=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},s={begin:/\{/,end:/\}/,contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(i,{begin:/:/})].concat(t),illegal:"\\S"},r={begin:"\\[",end:"\\]",contains:[e.inherit(i)],illegal:"\\S"};return a.push(s,r),t.forEach((function(e){a.push(e)})),{name:"JSON",contains:a,keywords:n,illegal:"\\S"}},Le="\\.([0-9](_*[0-9])*)",Be="[0-9a-fA-F](_*[0-9a-fA-F])*",$e={className:"number",variants:[{begin:`(\\b([0-9](_*[0-9])*)((${Le})|\\.)?|(${Le}))[eE][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:`\\b([0-9](_*[0-9])*)((${Le})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${Le})[fFdD]?\\b`},{begin:"\\b([0-9](_*[0-9])*)[fFdD]\\b"},{begin:`\\b0[xX]((${Be})\\.?|(${Be})?\\.(${Be}))[pP][+-]?([0-9](_*[0-9])*)[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${Be})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};var Ie=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},s={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(s);const r={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(s,{className:"meta-string"})]}]},l=$e,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,r,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,r,o,s,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},r,o]},s,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},l]}};function je(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var ze=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:je(/\[.+?\]\(/,/[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 s=[n,t];return a.contains=a.contains.concat(s),i.contains=i.contains.concat(s),s=s.concat(a,i),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:s},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:s}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},a,i,{className:"quote",begin:"^>\\s+",contains:s,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 Pe=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 Ue=function(e){const n={$pattern:/-?[A-z\.\-]+\b/,keyword:"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter",built_in:"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write"},t={begin:"`[\\s\\S]",relevance:0},a={className:"variable",variants:[{begin:/\$\B/},{className:"keyword",begin:/\$this/},{begin:/\$[\w\d][\w\d_:]*/}]},i={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[t,a,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},s={className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},r=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]}),o={className:"built_in",variants:[{begin:"(".concat("Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where",")+(-)[\\w\\d]+")}]},l={className:"class",beginKeywords:"class enum",end:/\s*[{]/,excludeEnd:!0,relevance:0,contains:[e.TITLE_MODE]},c={className:"function",begin:/function\s+/,end:/\s*\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:"function",relevance:0,className:"keyword"},{className:"title",begin:/\w[\w\d]*((-)[\w\d]+)*/,relevance:0},{begin:/\(/,end:/\)/,className:"params",relevance:0,contains:[a]}]},g={begin:/using\s/,end:/$/,returnBegin:!0,contains:[i,s,{className:"keyword",begin:/(using|assembly|command|module|namespace|type)/}]},d={variants:[{className:"operator",begin:"(".concat("-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor",")\\b")},{className:"literal",begin:/(-)[\w\d]+/,relevance:0}]},u={className:"function",begin:/\[.*\]\s*[\w]+[ ]??\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:"keyword",begin:"(".concat(n.keyword.toString().replace(/\s/g,"|"),")\\b"),endsParent:!0,relevance:0},e.inherit(e.TITLE_MODE,{endsParent:!0})]},b=[u,r,t,e.NUMBER_MODE,i,s,o,a,{className:"literal",begin:/\$(null|true|false)\b/},{className:"selector-tag",begin:/@\B/,relevance:0}],m={begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat("self",b,{begin:"("+["string","char","byte","int","long","bool","decimal","single","double","DateTime","xml","array","hashtable","void"].join("|")+")",className:"built_in",relevance:0},{className:"type",begin:/[\.\w\d]+/,relevance:0})};return u.contains.unshift(m),{name:"PowerShell",aliases:["ps","ps1"],case_insensitive:!0,keywords:n,contains:b.concat(l,c,g,d,m)}};var Ke=function(e){var n="[ \\t\\f]*",t=n+"[:=]"+n,a="[ \\t\\f]+",i="("+t+"|"+"[ \\t\\f]+)",s="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",r="([^\\\\:= \\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:s+t,relevance:1},{begin:s+a,relevance:0}],contains:[{className:"attr",begin:s,endsParent:!0,relevance:0}],starts:o},{begin:r+i,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:r,endsParent:!0,relevance:0}],starts:o},{className:"attr",relevance:0,begin:r+n+"$"}]}};function He(...e){return e.map((e=>{return(n=e)?"string"==typeof n?n:n.source:null;var n})).join("")}var Ze=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:">"},s=[e.COMMENT("#","$",{contains:[a]}),e.COMMENT("^=begin","^=end",{contains:[a],relevance:10}),e.COMMENT("^__END__","\\n$")],r={className:"subst",begin:/#\{/,end:/\}/,keywords:t},o={className:"string",contains:[e.BACKSLASH_ESCAPE,r],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,r]})]}]},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(s)},{className:"function",begin:He(/def\s+/,(u=n+"\\s*(\\(|;|$)",He("(?=",u,")"))),relevance:0,keywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),g].concat(s)},{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,r],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,s),relevance:0}].concat(i,s);var u;r.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 s.unshift(i),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:t,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(b).concat(s).concat(d)}};var Ge=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},s={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]},r={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,r,s,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}};var qe=function(e){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#]/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}};function Fe(e){return e?"string"==typeof e?e:e.source:null}function We(...e){return e.map((e=>Fe(e))).join("")}function Qe(...e){return"("+e.map((e=>Fe(e))).join("|")+")"}var Xe=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"],s=["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"],r=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:We(/\b/,Qe(...r),/\s*\(/),keywords:{built_in:r}};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(...s),keywords:{$pattern:/[\w\.]+/,keyword:o.concat(s),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 Ve(e){return e?"string"==typeof e?e:e.source:null}function Je(e){return Ye("(?=",e,")")}function Ye(...e){return e.map((e=>Ve(e))).join("")}function en(...e){return"("+e.map((e=>Ve(e))).join("|")+")"}var nn=function(e){const n=Ye(/[A-Z_]/,Ye("(",/[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:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),r=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,r,s,i,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[a,i,r,s]}]}]},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:Ye(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:o}]},{className:"tag",begin:Ye(/<\//,Je(Ye(n,/>/))),contains:[{className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}};var tn=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,{}[\]]+/}]}),s={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"},r={end:",",endsWithParent:!0,excludeEnd:!0,keywords:n,relevance:0},o={begin:/\{/,end:/\}/,contains:[r],illegal:"\\n",relevance:0},l={begin:"\\[",end:"\\]",contains:[r],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}},s,{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},o,l,a],g=[...c];return g.pop(),g.push(i),r.contains=g,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:c}};!function(){"use strict";ne.registerLanguage("asciidoc",ae),ne.registerLanguage("bash",se),ne.registerLanguage("css",ue),ne.registerLanguage("diff",be),ne.registerLanguage("dockerfile",me),ne.registerLanguage("dos",he),ne.registerLanguage("gradle",pe),ne.registerLanguage("groovy",Ee),ne.registerLanguage("http",Ne),ne.registerLanguage("java",Me),ne.registerLanguage("javascript",Ce),ne.registerLanguage("json",De),ne.registerLanguage("kotlin",Ie),ne.registerLanguage("markdown",ze),ne.registerLanguage("nix",Pe),ne.registerLanguage("powershell",Ue),ne.registerLanguage("properties",Ke),ne.registerLanguage("ruby",Ze),ne.registerLanguage("scala",Ge),ne.registerLanguage("shell",qe),ne.registerLanguage("sql",Xe),ne.registerLanguage("xml",nn),ne.registerLanguage("yaml",tn),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,n){let o=t.nextElementSibling;for(;o;){if(o.matches(e))return o;if(o.matches(n))return;o=o.nextElementSibling}}(t,".colist",".listingblock");s&&c.append(s);const i=n('
'+o+"
");return i.dataset.blockName=o,c.dataset.blockName=o,e.append(i),{tabElement:i,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"))i(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 i(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=i(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/docs/v1/js/site.js.map b/docs/v1/js/site.js.map new file mode 100755 index 0000000..89de670 --- /dev/null +++ b/docs/v1/js/site.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["site/src/main/js/site/anchorrewrite.js","site/anchorrewrite.js","site/src/main/js/site/author.js","site/author.js","site/node_modules/browser-pack-flat/_prelude","site/node_modules/lodash/_baseDelay.js","site/codetools.js","site/node_modules/lodash/identity.js","site/node_modules/lodash/_apply.js","site/node_modules/lodash/_overRest.js","site/node_modules/lodash/constant.js","site/node_modules/lodash/_freeGlobal.js","site/node_modules/lodash/_root.js","site/node_modules/lodash/_Symbol.js","site/node_modules/lodash/_getRawTag.js","site/node_modules/lodash/_objectToString.js","site/node_modules/lodash/_baseGetTag.js","site/node_modules/lodash/isObject.js","site/node_modules/lodash/isFunction.js","site/node_modules/lodash/_isMasked.js","site/node_modules/lodash/_coreJsData.js","site/node_modules/lodash/_toSource.js","site/node_modules/lodash/_baseIsNative.js","site/node_modules/lodash/_getValue.js","site/node_modules/lodash/_getNative.js","site/node_modules/lodash/_defineProperty.js","site/node_modules/lodash/_baseSetToString.js","site/node_modules/lodash/_shortOut.js","site/node_modules/lodash/_setToString.js","site/node_modules/lodash/_baseRest.js","site/node_modules/lodash/_trimmedEndIndex.js","site/node_modules/lodash/_baseTrim.js","site/node_modules/lodash/isObjectLike.js","site/node_modules/lodash/isSymbol.js","site/node_modules/lodash/toNumber.js","site/node_modules/lodash/delay.js","site/src/main/js/site/codetools.js","site/node_modules/browser-pack-flat/_postlude","site/node_modules/highlight.js/lib/core.js","site/highlight.js","site/node_modules/highlight.js/lib/languages/asciidoc.js","site/node_modules/highlight.js/lib/languages/bash.js","site/node_modules/highlight.js/lib/languages/css.js","site/node_modules/highlight.js/lib/languages/diff.js","site/node_modules/highlight.js/lib/languages/dockerfile.js","site/node_modules/highlight.js/lib/languages/dos.js","site/node_modules/highlight.js/lib/languages/gradle.js","site/node_modules/highlight.js/lib/languages/groovy.js","site/node_modules/highlight.js/lib/languages/http.js","site/node_modules/highlight.js/lib/languages/java.js","site/node_modules/highlight.js/lib/languages/javascript.js","site/node_modules/highlight.js/lib/languages/json.js","site/node_modules/highlight.js/lib/languages/kotlin.js","site/node_modules/highlight.js/lib/languages/markdown.js","site/node_modules/highlight.js/lib/languages/nix.js","site/node_modules/highlight.js/lib/languages/powershell.js","site/node_modules/highlight.js/lib/languages/properties.js","site/node_modules/highlight.js/lib/languages/ruby.js","site/node_modules/highlight.js/lib/languages/scala.js","site/node_modules/highlight.js/lib/languages/shell.js","site/node_modules/highlight.js/lib/languages/sql.js","site/node_modules/highlight.js/lib/languages/xml.js","site/node_modules/highlight.js/lib/languages/yaml.js","site/src/main/js/site/highlight.js","site/src/main/js/site/tabs.js","site/tabs.js","site/toc.js","site/node_modules/lodash/now.js","site/node_modules/lodash/debounce.js","site/node_modules/lodash/throttle.js","site/src/main/js/site/toc.js"],"names":["onChange","element","document","getElementById","anchor","window","location","hash","substr","rewrites","seen","console","debug","includes","error","push","updateAnchor","JSON","parse","innerHTML","addEventListener","candidate","lastAuthorElement","classList","contains","nextElementSibling","add","markLastAuthor","_$baseDelay_3","func","wait","args","TypeError","setTimeout","apply","undefined","_$identity_25","value","_$apply_2","thisArg","length","call","nativeMax","Math","max","_$overRest_17","start","transform","arguments","index","array","Array","otherArgs","this","_$constant_23","_$freeGlobal_11","global","freeGlobal","Object","self","freeSelf","_$root_18","Function","_$Symbol_1","Symbol","objectProto","prototype","hasOwnProperty","nativeObjectToString","toString","symToStringTag","toStringTag","_$getRawTag_13","isOwn","tag","unmasked","e","result","__nativeObjectToString_16","_$objectToString_16","__symToStringTag_4","_$baseGetTag_4","_$isObject_27","type","uid","_$isFunction_26","_$coreJsData_9","maskSrcKey","exec","keys","IE_PROTO","_$isMasked_15","funcToString","_$toSource_21","reIsHostCtor","__funcProto_5","__objectProto_5","__funcToString_5","__hasOwnProperty_5","reIsNative","RegExp","replace","_$baseIsNative_5","test","_$getValue_14","object","key","_$getNative_12","_$defineProperty_10","_$baseSetToString_7","string","configurable","enumerable","writable","nativeNow","Date","now","_$shortOut_20","count","lastCalled","stamp","remaining","_$setToString_19","reWhitespace","_$trimmedEndIndex_22","charAt","reTrimStart","_$baseTrim_8","slice","_$isObjectLike_28","_$isSymbol_29","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","parseInt","_$toNumber_30","other","valueOf","isBinary","_$delay_24","_$baseRest_6","onCopyButtonClick","preElement","copy","querySelector","cloneNode","hideWhenFoldedElement","querySelectorAll","parentNode","removeChild","text","innerText","navigator","clipboard","writeText","then","markClicked","bind","clearClicked","remove","onFoldUnfoldButtonClick","codeElement","unfolding","toggle","updateFoldUnfoldButton","button","unfold","label","title","codeToolsElement","createElement","className","addButtons","appendChild","numberOfButtons","hasHideWhenFoldedSpans","foldUnfoldButton","createButton","addFoldUnfoldButton","copyButton","copiedPopup","addCopyButton","buttonElement","labelElement","createTextNode","addCodeToolElements","deepFreeze","obj","Map","clear","delete","set","Error","Set","freeze","getOwnPropertyNames","forEach","name","prop","isFrozen","deepFreezeEs6","_default","default","Response","constructor","mode","data","isMatchIgnored","ignoreMatch","escapeHTML","inherit","original","objects","create","emitsWrappingTags","node","kind","HTMLRenderer","parseTree","options","buffer","classPrefix","walk","addText","openNode","sublanguage","span","closeNode","TokenTree","rootNode","children","stack","top","root","pop","closeAllNodes","toJSON","stringify","builder","_walk","static","child","every","el","join","_collapse","TokenTreeEmitter","super","addKeyword","addSublanguage","emitter","toHTML","finalize","source","re","BACKREF_RE","IDENT_RE","UNDERSCORE_IDENT_RE","NUMBER_RE","C_NUMBER_RE","BINARY_NUMBER_RE","BACKSLASH_ESCAPE","begin","relevance","APOS_STRING_MODE","end","illegal","QUOTE_STRING_MODE","PHRASAL_WORDS_MODE","COMMENT","modeOptions","C_LINE_COMMENT_MODE","C_BLOCK_COMMENT_MODE","HASH_COMMENT_MODE","NUMBER_MODE","C_NUMBER_MODE","BINARY_NUMBER_MODE","CSS_NUMBER_MODE","REGEXP_MODE","TITLE_MODE","UNDERSCORE_TITLE_MODE","METHOD_GUARD","MODES","__proto__","MATCH_NOTHING_RE","RE_STARTERS_RE","SHEBANG","opts","beginShebang","binary","map","x","concat","m","resp","END_SAME_AS_BEGIN","assign","_beginMatch","skipIfhasPrecedingDot","match","response","input","beginKeywords","parent","split","__beforeBegin","keywords","compileIllegal","_parent","isArray","either","compileMatch","compileRelevance","COMMON_KEYWORDS","compileKeywords","rawKeywords","caseInsensitive","compiledKeywords","compileList","keywordList","toLowerCase","keyword","pair","scoreForKeyword","providedScore","Number","commonKeyword","compileLanguage","language","plugins","langRe","case_insensitive","MultiRegex","matchIndexes","regexes","matchAt","position","addRule","countMatchGroups","compile","terminators","matcherRe","regexps","separator","numCaptures","regex","offset","out","substring","String","lastIndex","s","i","findIndex","matchData","splice","ResumableMultiRegex","rules","multiRegexes","regexIndex","getMatcher","matcher","resumingScanAtSamePosition","considerAll","m2","compilerExtensions","classNameAliases","compileMode","cmode","isCompiled","ext","keywordPattern","$pattern","lexemes","keywordPatternRe","beginRe","endSameAsBegin","endsWithParent","endRe","terminatorEnd","illegalRe","c","variants","cachedVariants","variant","dependencyOnParent","starts","expandOrCloneMode","mm","term","rule","buildModeRegex","BuildVuePlugin","hljs","Component","props","detectedLanguage","unknownLanguage","computed","highlighted","autoDetect","getLanguage","warn","code","highlightAuto","highlight","ignoreIllegals","autodetect","Boolean","render","class","domProps","VuePlugin","install","Vue","component","mergeHTMLPlugin","originalStream","nodeStream","resultNode","processed","nodeStack","selectStream","event","open","attributeString","attr","nodeName","attributes","close","stream","reverse","mergeStreams","_nodeStream","firstChild","nextSibling","nodeType","nodeValue","seenDeprecations","message","log","deprecated","version","escape$1","inherit$1","NO_MATCH","_$highlight_1","languages","aliases","SAFE_MODE","fixMarkupRe","LANGUAGE_NOT_FOUND","PLAINTEXT_LANGUAGE","disableAutodetect","noHighlightRe","languageDetectRe","tabReplace","useBR","__emitter","shouldNotHighlight","languageName","codeOrlanguageName","optionsOrCode","continuation","context","fire","_highlight","codeToHighlight","keywordData","matchText","processBuffer","subLanguage","modeBuffer","continuations","processSubLanguage","buf","keywordRelevance","startsWith","cssClass","processKeywords","startNewMode","endOfMode","matchPlusRemainder","matched","lexeme","endsParent","doIgnore","resumeScanAtSamePosition","doBeginMatch","newMode","beforeCallbacks","cb","skip","excludeBegin","returnBegin","doEndMatch","endMode","origin","returnEnd","excludeEnd","lastMatch","processLexeme","textBeforeMatch","err","badRule","iterations","md","list","current","unshift","item","processContinuations","processedCount","floor","illegalBy","msg","sofar","errorRaised","languageSubset","plaintext","justTextHighlightResult","results","filter","autoDetection","sorted","sort","a","b","supersetOf","best","secondBest","second_best","brPlugin","TAB_REPLACE_RE","tabReplacePlugin","highlightElement","block","classes","find","_class","blockLanguage","textContent","currentLang","resultLang","updateClassName","relavance","initHighlighting","called","wantsHighlight","highlightAll","readyState","registerAliases","aliasList","alias","lang","plugin","fixMarkup","arg","html","highlightBlock","configure","userOptions","initHighlightingOnLoad","registerLanguage","languageDefinition","error$1","rawDefinition","unregisterLanguage","listLanguages","requireLanguage","addPlugin","upgradePluginAPI","vuePlugin","debugMode","safeMode","versionString","HLJS","__concat_2","__source_2","_$asciidoc_2","STRONG","EMPHASIS","__concat_3","__source_3","_$bash_3","VAR","BRACED_VAR","SUBST","HERE_DOC","QUOTE_STRING","ARITHMETIC","KNOWN_SHEBANG","FUNCTION","literal","built_in","TAGS","MEDIA_FEATURES","PSEUDO_CLASSES","PSEUDO_ELEMENTS","ATTRIBUTES","lookahead","__source_4","__concat_4","_$css_4","modes","IMPORTANT","HEXCOLOR","ATTRIBUTE_SELECTOR_MODE","__MODES_4","STRINGS","keyframePosition","attribute","_$diff_5","_$dockerfile_6","_$dos_7","_$gradle_8","__lookahead_9","__source_9","__concat_9","_$groovy_9","REGEXP","NUMBER","STRING","__concat_10","__source_10","_$http_10","VERSION","HEADER","HEADERS_AND_BODY","frac","hexDigits","NUMERIC","_$java_11","JAVA_IDENT_RE","KEYWORDS","ANNOTATION","__IDENT_RE_12","LITERALS","BUILT_INS","__lookahead_12","__concat_12","__source_12","_$javascript_12","IDENT_RE$1","FRAGMENT","XML_TAG","isTrulyOpeningTag","afterMatchIndex","nextChar","after","indexOf","hasClosingTag","KEYWORDS$1","decimalInteger","HTML_TEMPLATE","CSS_TEMPLATE","TEMPLATE_STRING","SUBST_INTERNALS","SUBST_AND_COMMENTS","PARAMS_CONTAINS","PARAMS","exports","_$json_13","ALLOWED_COMMENTS","TYPES","VALUE_CONTAINER","OBJECT","ARRAY","__frac_14","__hexDigits_14","__NUMERIC_14","_$kotlin_14","LABEL","VARIABLE","ANNOTATION_USE_SITE","KOTLIN_NUMBER_MODE","KOTLIN_NESTED_COMMENT","KOTLIN_PAREN_TYPE","KOTLIN_PAREN_TYPE2","__concat_15","__source_15","_$markdown_15","INLINE_HTML","LINK","BOLD","ITALIC","CONTAINABLE","_$nix_16","NIX_KEYWORDS","ANTIQUOTE","EXPRESSIONS","_$powershell_17","BACKTICK_ESCAPE","APOS_STRING","PS_COMMENT","CMDLETS","PS_CLASS","PS_FUNCTION","PS_USING","PS_ARGUMENTS","PS_METHODS","GENTLEMANS_SET","PS_TYPE","_$properties_18","WS0","EQUAL_DELIM","WS_DELIM","DELIM","KEY_ALPHANUM","KEY_OTHER","DELIM_AND_VALUE","__concat_19","__source_19","_$ruby_19","RUBY_METHOD_RE","RUBY_KEYWORDS","YARDOCTAG","IRB_OBJECT","COMMENT_MODES","digits","RUBY_DEFAULT_CONTAINS","IRB_DEFAULT","_$scala_20","TYPE","NAME","CLASS","METHOD","_$shell_21","__source_22","__concat_22","__either_22","_$sql_22","COMMENT_MODE","RESERVED_FUNCTIONS","COMBOS","FUNCTIONS","FUNCTION_CALL","exceptions","when","qualifyFn","reduceRelevancy","__source_23","__lookahead_23","__concat_23","__either_23","_$xml_23","TAG_NAME_RE","XML_ENTITIES","XML_META_KEYWORDS","XML_META_PAR_KEYWORDS","APOS_META_STRING_MODE","QUOTE_META_STRING_MODE","TAG_INTERNALS","_$yaml_24","URI_CHARACTERS","CONTAINER_STRING","TIMESTAMP","VALUE_MODES","ignoreUnescapedHTML","createTabsElement","primaryElement","tabsElement","createElementFromHtml","prepend","createTab","blockElement","content","colist","selector","stopSelector","sibling","matches","append","tabElement","dataset","blockName","template","findPrimaryElement","secondaryElement","previousElementSibling","onTabClick","tabId","localStorage","setItem","getTabId","select","id","tab","addTabs","getItem","configureTabs","_$isObject_10","_$freeGlobal_4","_$root_7","_$now_13","_$trimmedEndIndex_8","_$baseTrim_3","_$getRawTag_5","__nativeObjectToString_6","_$objectToString_6","__symToStringTag_2","_$baseGetTag_2","_$isObjectLike_11","_$isSymbol_12","_$toNumber_15","nativeMin","min","_$debounce_9","lastArgs","lastThis","maxWait","timerId","lastCallTime","lastInvokeTime","leading","maxing","trailing","invokeFunc","time","leadingEdge","timerExpired","shouldInvoke","timeSinceLastCall","trailingEdge","timeWaiting","remainingWait","debounced","isInvoking","clearTimeout","cancel","flush","_$throttle_14","tocElement","toggleTocElement","contentElement","headingElements","hrefToTocAnchorElement","headingElementToTocElement","lastActiveTocElement","disableOnScroll","onLocationHashChange","updateFixedPositionClass","tocAnchorElement","get","headingElement","getHeadingElementByHref","isInViewport","activateTocElement","parentElement","onEndScroll","maxHeadingLevel","getMaxHeadingLevel","headingSelectors","headingLevel","listElement","getHeadingLevel","findHeadingElements","href","getAttribute","buildHrefToTocAnchorElement","getChildAnchorHref","buildHeadingElementToTocElement","onScroll","onResize","onTocElementClick","onToggleTocClick","activateTopHeadingTocElement","target","stopPropagation","body","documentElement","removeEventListener","computedStyle","getComputedStyle","bannerHeight","getPropertyValue","getTop","topHeadingElement","topHeadingPos","offsetTop","getTopHeading","achorElement","deactivateTocElement","scrollTop","rect","getBoundingClientRect","bottom","innerHeight","clientHeight"],"mappings":"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CL9F,UAAW,cAKbka,EAAe,CACnBla,UAAW,SACX2F,MAAO,IAAKG,IAAK,IACjBlP,SAAU,CACRkX,EAAKpI,iBACLoU,EACAE,IAGJA,EAAMpjB,SAAST,KAAK+jB,GACpB,MASMC,EAAa,CACjBxU,MAAO,SACPG,IAAK,OACLlP,SAAU,CACR,CAAE+O,MAAO,gBAAiB3F,UAAW,UACrC8N,EAAKvH,YACLuT,IAcEM,EAAgBtM,EAAK3G,QAAQ,CACjCG,OAAQ,IAZa,CACrB,OACA,OACA,MACA,KACA,MACA,MACA,OACA,OACA,QAG2B7C,KAAK,QAChCmB,UAAW,KAEPyU,EAAW,CACfra,UAAW,WACX2F,MAAO,4BACPwO,aAAa,EACbvd,SAAU,CAACkX,EAAKvL,QAAQuL,EAAKlH,WAAY,CAACjB,MAAO,gBACjDC,UAAW,GAGb,MAAO,CACLlE,KAAM,OACN2P,QAAS,CAAC,KAAM,OAChB9I,SAAU,CACRkE,SAAU,gBACVnD,QACE,+DACFgR,QACE,aACFC,SAGE,6uBAeJ3jB,SAAU,CACRwjB,EACAtM,EAAK3G,UACLkT,EACAF,EACArM,EAAKxH,kBACL2T,EACAC,EA3EkB,CACpBla,UAAW,GACX2F,MAAO,OAGW,CAClB3F,UAAW,SACX2F,MAAO,IAAKG,IAAK,KAuEfgU,GF0wFN,EG76FA,MAuBMU,GAAO,CACX,IACA,OACA,UACA,UACA,QACA,QACA,IACA,aACA,OACA,SACA,SACA,UACA,OACA,OACA,KACA,MACA,UACA,MACA,MACA,KACA,KACA,KACA,WACA,aACA,SACA,SACA,OACA,KACA,KACA,KACA,KACA,KACA,KACA,SACA,SACA,OACA,IACA,SACA,MACA,QACA,MACA,MACA,QACA,SACA,KACA,OACA,OACA,OACA,MACA,SACA,KACA,IACA,IACA,QACA,OACA,UACA,OACA,SACA,UACA,MACA,QACA,QACA,KACA,WACA,QACA,KACA,QACA,OACA,KACA,KACA,MACA,SAGIC,GAAiB,CACrB,YACA,cACA,eACA,QACA,cACA,cACA,sBACA,gBACA,eACA,eACA,gBACA,OACA,SACA,QACA,kBACA,aACA,cACA,iBACA,kBACA,UACA,uBACA,mBACA,yBACA,+BACA,aACA,OACA,YACA,SACA,QAEA,YACA,YACA,aACA,cAIIC,GAAiB,CACrB,SACA,WACA,QACA,UACA,UACA,UACA,UACA,MACA,WACA,OACA,QACA,UACA,QACA,cACA,gBACA,aACA,SACA,QACA,gBACA,eACA,MACA,OACA,eACA,QACA,gBACA,WACA,UACA,KACA,OACA,aACA,eACA,OACA,OACA,aACA,MACA,YACA,UACA,iBACA,eACA,mBACA,cACA,aACA,eACA,WACA,eACA,OACA,oBACA,YACA,aACA,WACA,QACA,OACA,QACA,SACA,gBACA,eACA,QACA,UACA,SAIIC,GAAkB,CACtB,QACA,WACA,SACA,MACA,aACA,eACA,aACA,gBACA,SACA,OACA,cACA,YACA,UACA,kBAGIC,GAAa,CACjB,gBACA,cACA,aACA,YACA,kBACA,sBACA,qBACA,sBACA,4BACA,iBACA,uBACA,4BACA,OACA,sBACA,aACA,wBACA,kBACA,mBACA,mBACA,oBACA,sBACA,oBACA,kBACA,SACA,gBACA,sBACA,4BACA,6BACA,sBACA,sBACA,kBACA,eACA,eACA,sBACA,sBACA,qBACA,sBACA,qBACA,cACA,oBACA,oBACA,oBACA,gBACA,eACA,qBACA,qBACA,qBACA,iBACA,eACA,aACA,mBACA,yBACA,0BACA,mBACA,mBACA,eACA,SACA,uBACA,aACA,aACA,cACA,eACA,eACA,eACA,QACA,OACA,YACA,QACA,eACA,cACA,aACA,cACA,oBACA,oBACA,oBACA,cACA,eACA,UACA,UACA,oBACA,gBACA,SACA,YACA,UACA,cACA,SACA,OACA,aACA,iBACA,YACA,YACA,cACA,YACA,QACA,OACA,eACA,cACA,wBACA,eACA,yBACA,YACA,mBACA,iBACA,eACA,aACA,eACA,yBACA,0BACA,cACA,SACA,UACA,OACA,oBACA,kBACA,mBACA,WACA,UACA,UACA,kBACA,OACA,iBACA,cACA,aACA,mBACA,sBACA,kBACA,SACA,gBACA,cACA,eACA,aACA,QACA,OACA,aACA,YACA,aACA,YACA,WACA,YACA,WACA,YACA,SACA,OACA,SACA,aACA,kBACA,UACA,QACA,UACA,UACA,gBACA,iBACA,gBACA,gBACA,WACA,gBACA,aACA,aACA,UACA,iBACA,eACA,gBACA,cACA,mBACA,oBACA,oBACA,cACA,qBACA,iBACA,WACA,SACA,SACA,QACA,MACA,WACA,eACA,aACA,kBACA,kBACA,wBACA,uBACA,wBACA,cACA,gBACA,iBACA,cACA,iBACA,0BACA,MACA,YACA,mBACA,kBACA,aACA,mBACA,sBACA,sBACA,6BACA,eACA,iBACA,aACA,cACA,SACA,QACA,aACA,eACA,YACA,WAGAxK,UAsBF,SAASyK,GAAU1V,GACjB,OAOF,YAAmBhO,GAEjB,OADeA,EAAKoQ,KAAKC,GApB3B,SAAgBrC,GACd,OAAKA,EACa,iBAAPA,EAAwBA,EAE5BA,EAAGD,OAHM,IHq7FlB,CGl6FiC4V,CAAOtT,KAAI/C,KAAK,GHm7FjD,CG37FSsW,CAAO,MAAO5V,EAAI,IHk7F3B,CGpxFA,IAAA6V,GA3IA,SAAalN,GACX,MAAMmN,EArdM,CAACnN,IACN,CACLoN,UAAW,CACTlb,UAAW,OACX2F,MAAO,cAETwV,SAAU,CACRnb,UAAW,SACX2F,MAAO,oCAETyV,wBAAyB,CACvBpb,UAAW,gBACX2F,MAAO,KACPG,IAAK,KACLC,QAAS,IACTnP,SAAU,CACRkX,EAAKjI,iBACLiI,EAAK9H,sBAocGqV,CAAMvN,GAWdwN,EAAU,CACdxN,EAAKjI,iBACLiI,EAAK9H,mBAGP,MAAO,CACLtE,KAAM,MACNsI,kBAAkB,EAClBjE,QAAS,UACTwC,SAAU,CACRgT,iBAAkB,WAEpBpP,iBAAkB,CAGhBoP,iBAAkB,gBAEpB3kB,SAAU,CACRkX,EAAKzH,qBAxBa,CACpBV,MAAO,gCA2BLmI,EAAKpH,gBACL,CACE1G,UAAW,cACX2F,MAAO,kBACPC,UAAW,GAEb,CACE5F,UAAW,iBACX2F,MAAO,6BACPC,U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,EAAKzH,uBAGT6V,EACAc,GV2iIN,EW1tIA,MAAMC,GAAW,2BACXF,GAAW,CACf,KACA,KACA,KACA,KACA,MACA,QACA,UACA,MACA,MACA,WACA,KACA,SACA,OACA,OACA,QACA,QACA,aACA,OACA,QACA,OACA,UACA,MACA,SACA,WACA,SACA,SACA,MACA,QACA,QACA,QAIA,WACA,QACA,QACA,SACA,SACA,OACA,SACA,WAEIG,GAAW,CACf,OACA,QACA,OACA,YACA,MACA,YAoFIC,GAAY,GAAG1V,OAlCI,CACvB,cACA,aACA,gBACA,eAEA,UACA,UAEA,OACA,WACA,QACA,aACA,WACA,YACA,qBACA,YACA,qBACA,SACA,YAGyB,CACzB,YACA,OACA,QACA,UACA,SACA,WACA,eACA,SACA,UA9EY,CACZ,OACA,WACA,SACA,OACA,OACA,SACA,SACA,SACA,WACA,UACA,QACA,SACA,MACA,MACA,UACA,UACA,QACA,UACA,OACA,UACA,eACA,aACA,aACA,YACA,cACA,cACA,eACA,QACA,aACA,oBACA,cACA,gBACA,iBACA,UAGkB,CAClB,YACA,gBACA,aACA,iBACA,cACA,YACA,aAgEF,SAAS2V,GAAUjY,GACjB,OAAOkY,GAAO,MAAOlY,EAAI,IX+tI3B,CWxtIA,SAASkY,MAAUlmB,GAEjB,OADeA,EAAKoQ,KAAKC,IAAM8V,OApBjBnY,EAoBwBqC,GAlBpB,iBAAPrC,EAAwBA,EAE5BA,EAAGD,OAHM,KADlB,IAAgBC,CAoB0B,IAAEV,KAAK,GXguIjD,CW/yHA,IAAA8Y,GAraA,SAAoBzP,GAQlB,MAMM0P,EAAaP,GACbQ,EACG,KADHA,EAEC,MAEDC,EAAU,CACd/X,MAAO,sBACPG,IAAK,4BAKL6X,kBAAmB,CAAC3V,EAAOC,KACzB,MAAM2V,EAAkB5V,EAAM,GAAGpQ,OAASoQ,EAAM3P,MAC1CwlB,EAAW7V,EAAME,MAAM0V,GAIZ,MAAbC,EAMa,MAAbA,IA9Bc,EAAC7V,GAAS8V,YAC9B,MAAMhkB,EAAM,KAAOkO,EAAM,GAAG5K,MAAM,GAElC,OAAgB,IADJ4K,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W,SACX2F,MAAO,uBAmEL6c,EACAG,EACAD,EACA5U,EAAKtH,cA5HU,CACjBxG,UAAW,OACX2F,MAAO,enBi4MX,EoB/2MA,IAAAid,GApBA,SAAe9U,GACb,MAAO,CACLpM,KAAM,gBACN2P,QAAS,CAAE,WACXza,SAAU,CACR,CACEoJ,UAAW,OAIX2F,MAAO,iCACP4H,OAAQ,CACNzH,IAAK,gBACL8M,YAAa,UpBq5MvB,EqBl6MA,SAASiQ,GAAO1d,GACd,OAAKA,EACa,iBAAPA,EAAwBA,EAE5BA,EAAGD,OAHM,IrBm7MlB,CqBz6MA,SAAS4d,MAAU3rB,GAEjB,OADeA,EAAKoQ,KAAKC,GAAMqb,GAAOrb,KAAI/C,KAAK,GrBi7MjD,CqBt6MA,SAASse,MAAU5rB,GAEjB,MADe,IAAMA,EAAKoQ,KAAKC,GAAMqb,GAAOrb,KAAI/C,KAAK,KAAO,GrBi7M9D,CqBxxLA,IAAAue,GA/oBA,SAAalV,GACX,MAAMmV,EAAenV,EAAK5H,QAAQ,KAAM,KAmBlCgX,EAAW,CACf,OACA,QAGA,WAUI2B,EAAQ,CACZ,SACA,SACA,OACA,UACA,OACA,YACA,OACA,OACA,MACA,WACA,UACA,QACA,MACA,UACA,WACA,QACA,QACA,WACA,UACA,OACA,MACA,WACA,OACA,YACA,UACA,UACA,aAmYIqE,EAAqB,CACzB,MACA,OACA,YACA,OACA,OACA,MACA,OACA,OACA,UACA,WACA,OACA,MACA,OACA,QACA,YACA,aACA,YACA,aACA,QACA,UACA,MACA,UACA,cACA,QACA,aACA,gBACA,cACA,cACA,iBACA,aACA,aACA,uBACA,aACA,MACA,aACA,OACA,UACA,KACA,MACA,QACA,QACA,MACA,MACA,MACA,YACA,QACA,SACA,eACA,kBACA,kBACA,WACA,iBACA,QACA,OACA,YACA,YACA,aACA,iBACA,UACA,aACA,WACA,WACA,WACA,aACA,MACA,OACA,OACA,aACA,cACA,YACA,kBACA,MACA,MACA,OACA,YACA,kBACA,QACA,OACA,aACA,SACA,QACA,WACA,UACA,WACA,gBAwBIC,EAAS,CACb,eACA,cACA,cACA,cACA,WACA,cACA,iBACA,gBACA,cACA,gBACA,gBACA,eACA,cACA,aACA,cACA,iBAGIC,EAAYF,EAEZnG,EAAW,CArff,MACA,OACA,MACA,WACA,QACA,MACA,MACA,MACA,QACA,YACA,wBACA,KACA,aACA,OACA,aACA,KACA,OACA,SACA,gBACA,MACA,QACA,cACA,kBACA,UACA,SACA,SACA,OACA,UACA,OACA,KACA,OACA,SACA,cACA,WACA,OACA,OACA,OACA,UACA,OACA,cACA,YACA,mBACA,QACA,aACA,OACA,QACA,WACA,UACA,UACA,SACA,SACA,YACA,UACA,aACA,WACA,UACA,OACA,OACA,gBACA,MACA,OACA,QACA,YACA,aACA,SACA,QACA,OACA,YACA,UACA,kBACA,eACA,kCACA,eACA,eACA,cACA,iBACA,eACA,oBACA,eACA,eACA,mCACA,eACA,SACA,QACA,OACA,MACA,aACA,MACA,UACA,WACA,UACA,UACA,SACA,SACA,aACA,QACA,WACA,gBACA,aACA,WACA,SACA,OACA,UACA,OACA,UACA,OACA,QACA,MACA,YACA,gBACA,WACA,SACA,SACA,QACA,SACA,OACA,UACA,SACA,MACA,WACA,UACA,QACA,QACA,SACA,cACA,QACA,QACA,MACA,UACA,YACA,OACA,OACA,OACA,WACA,SACA,MACA,SACA,QACA,QACA,WACA,SACA,SACA,OACA,OACA,WACA,KACA,YACA,UACA,QACA,QACA,cACA,SACA,MACA,UACA,YACA,eACA,WACA,OACA,KACA,OACA,aACA,gBACA,cACA,cACA,iBACA,aACA,aACA,uBACA,aACA,MACA,WACA,QACA,aACA,UACA,OACA,UACA,OACA,OACA,aACA,UACA,KACA,QACA,YACA,iBACA,MACA,QACA,QACA,QACA,eACA,kBACA,UACA,MACA,SACA,QACA,SACA,MACA,SACA,MACA,WACA,SACA,QACA,WACA,WACA,UACA,QACA,QACA,MACA,KACA,OACA,YACA,MACA,YACA,QACA,OACA,SACA,UACA,eACA,oBACA,KACA,SACA,MACA,OACA,KACA,MACA,OACA,OACA,KACA,QACA,MACA,QACA,OACA,WACA,UACA,YACA,YACA,UACA,MACA,UACA,eACA,kBACA,kBACA,SACA,UACA,WACA,iBACA,QACA,WACA,YACA,UACA,UACA,YACA,MACA,QACA,OACA,QACA,OACA,YACA,MACA,aACA,cACA,YACA,YACA,aACA,iBACA,UACA,aACA,WACA,WACA,WACA,UACA,SACA,SACA,UACA,SACA,QACA,WACA,SACA,MACA,aACA,OACA,UACA,YACA,QACA,SACA,SACA,SACA,OACA,SACA,YACA,eACA,MACA,OACA,UACA,MACA,OACA,OACA,WACA,OACA,WACA,eACA,MACA,eACA,WACA,aACA,OACA,QACA,SACA,aACA,cACA,cACA,SACA,YACA,kBACA,WACA,MACA,YACA,SACA,cACA,cACA,QACA,cACA,MACA,OACA,OACA,OACA,YACA,gBACA,kBACA,KACA,WACA,YACA,kBACA,cACA,QACA,UACA,OACA,aACA,OACA,WACA,UACA,QACA,SACA,UACA,SACA,YACA,QACA,OACA,QACA,QACA,SACA,WACA,UACA,WACA,YACA,UACA,UACA,aACA,OACA,WACA,QACA,eACA,SACA,OACA,SACA,UACA,OAzXA,MACA,MACA,YACA,OACA,QACA,QACA,OACA,QA0f0DhH,QAAQzM,IAC1D4Z,EAAmBjtB,SAASqT,KAchC+Z,EAAgB,CACpB1d,MAAOmd,GAAO,KAAMC,MAAUK,GAAY,SAC1C7a,SAAU,CACRgS,SAAU6I,IAmBd,MAAO,CACL1hB,KAAM,MACNsI,kBAAkB,EAElBjE,QAAS,WACTwC,SAAU,CACRkE,SAAU,YACVnD,QArBJ,SAAyB0L,GAAMsO,WAACA,EAAUC,KAAEA,GAAQ,CAAA,GAClD,MAAMC,EAAYD,EAElB,OADAD,EAAaA,GAAc,GACpBtO,EAAKzN,KAAK4N,GACXA,EAAKnN,MAAM,WAAasb,EAAWrtB,SAASkf,GACvCA,EACEqO,EAAUrO,GACZ,GAAGA,MAEHA,GrBk7Mb,CqBr6MMsO,CAAgB1G,EAAU,CAAEwG,KAAO/b,GAAMA,EAAE5P,OAAS,IACtD0iB,QAAS4C,EACT3iB,KAAMskB,EACNtE,SAzF4B,CAC9B,kBACA,eACA,kCACA,eACA,eACA,iBACA,mCACA,eACA,eACA,cACA,cACA,eACA,YACA,oBACA,mBA4EA3jB,SAAU,CACR,CACE+O,MAAOod,MAAUI,GACjB5a,SAAU,CACRkE,SAAU,UACVnD,QAASyT,EAAStV,OAAO0b,GACzB7I,QAAS4C,EACT3iB,KAAMskB,IAGV,CACE7e,UAAW,OACX2F,MAAOod,GApmBX,mBACA,eACA,gBACA,qBAmmBEM,EA5Da,CACfrjB,UAAW,WACX2F,MAAO,cAvkBM,CACb3F,UAAW,SACXmN,SAAU,CACR,CACExH,MAAO,IACPG,IAAK,IACLlP,SAAU,CACR,CAAC+O,MAAO,UAKU,CACxBA,MAAO,IACPG,IAAK,IACLlP,SAAU,CAAE,CAAE+O,MAAO,QAsnBnBmI,EAAKtH,cACLsH,EAAKzH,qBACL4c,EA7Da,CACfjjB,UAAW,WACX2F,MAAO,gDACPC,UAAW,IrB6+Mf,EsB9lOA,SAAS8d,GAAOve,GACd,OAAKA,EACa,iBAAPA,EAAwBA,EAE5BA,EAAGD,OAHM,ItB+mOlB,CsBrmOA,SAASye,GAAUxe,GACjB,OAAOye,GAAO,MAAOze,EAAI,ItB4mO3B,CsB7lOA,SAASye,MAAUzsB,GAEjB,OADeA,EAAKoQ,KAAKC,GAAMkc,GAAOlc,KAAI/C,KAAK,GtB6mOjD,CsBlmOA,SAASof,MAAU1sB,GAEjB,MADe,IAAMA,EAAKoQ,KAAKC,GAAMkc,GAAOlc,KAAI/C,KAAK,KAAO,GtB6mO9D,CsBh4NA,IAAAqf,GAjOA,SAAahW,GAEX,MAAMiW,EAAcH,GAAO,SAlCpBA,GAAO,IAkCgC,gBAlCvB,MAkCyC,gBAE1DI,EAAe,CACnBhkB,UAAW,SACX2F,MAAO,oCAEHse,EAAoB,CACxBte,MAAO,KACP/O,SAAU,CACR,CACEoJ,UAAW,eACX2F,MAAO,sBACPI,QAAS,QAITme,EAAwBpW,EAAKvL,QAAQ0hB,EAAmB,CAC5Dte,MAAO,KACPG,IAAK,OAEDqe,EAAwBrW,EAAKvL,QAAQuL,EAAKjI,iBAAkB,CAChE7F,UAAW,gBAEPokB,EAAyBtW,EAAKvL,QAAQuL,EAAK9H,kBAAmB,CAClEhG,UAAW,gBAEPqkB,EAAgB,CACpBvX,gBAAgB,EAChB/G,QAAS,IACTH,UAAW,EACXhP,SAAU,CACR,CACEoJ,UAAW,OACX2F,MAhCe,mBAiCfC,UAAW,GAEb,CACED,MAAO,OACPC,UAAW,EACXhP,SAAU,CACR,CACEoJ,UAAW,SACX0T,YAAY,EACZvG,SAAU,CACR,CACExH,MAAO,IACPG,IAAK,IACLlP,SAAU,CAAEotB,IAEd,CACEre,MAAO,IACPG,IAAK,IACLlP,SAAU,CAAEotB,IAEd,CACEre,MAAO,sBAQrB,MAAO,CACLjE,KAAM,YACN2P,QAAS,CACP,OACA,QACA,MACA,OACA,MACA,MACA,MACA,QACA,MACA,OAEFrH,kBAAkB,EAClBpT,SAAU,CACR,CACEoJ,UAAW,OACX2F,MAAO,UACPG,IAAK,IACLF,UAAW,GACXhP,SAAU,CACRqtB,EACAG,EACAD,EACAD,EACA,CACEve,MAAO,KACPG,IAAK,KACLlP,SAAU,CACR,CACEoJ,UAAW,OACX2F,MAAO,UACPG,IAAK,IACLlP,SAAU,CACRqtB,EACAC,EACAE,EACAD,QAOZrW,EAAK5H,QACH,OACA,MACA,CACEN,UAAW,KAGf,CACED,MAAO,cACPG,IAAK,QACLF,UAAW,IAEboe,EACA,CACEhkB,UAAW,OACX2F,MAAO,SACPG,IAAK,MACLF,UAAW,IAEb,CACE5F,UAAW,MAOX2F,MAAO,iBACPG,IAAK,IACLyC,SAAU,CACR7G,KAAM,SAER9K,SAAU,CAAEytB,GACZ9W,OAAQ,CACNzH,IAAK,YACLyO,WAAW,EACX3B,YAAa,CACX,MACA,SAIN,CACE5S,UAAW,MAEX2F,MAAO,kBACPG,IAAK,IACLyC,SAAU,CACR7G,KAAM,UAER9K,SAAU,CAAEytB,GACZ9W,OAAQ,CACNzH,IAAK,aACLyO,WAAW,EACX3B,YAAa,CACX,aACA,aACA,SAKN,CACE5S,UAAW,MACX2F,MAAO,WAGT,CACE3F,UAAW,MACX2F,MAAOie,GACL,IACAD,GAAUC,GACRG,EAIAF,GAAO,MAAO,IAAK,SAGvB/d,IAAK,OACLlP,SAAU,CACR,CACEoJ,UAAW,OACX2F,MAAOoe,EACPne,UAAW,EACX2H,OAAQ8W,KAKd,CACErkB,UAAW,MACX2F,MAAOie,GACL,MACAD,GAAUC,GACRG,EAAa,OAGjBntB,SAAU,CACR,CACEoJ,UAAW,OACX2F,MAAOoe,EACPne,UAAW,GAEb,CACED,MAAO,IACPC,UAAW,EACX8N,YAAY,MtBinOxB,EuBxtOA,IAAA4Q,GAtKA,SAAcxW,GACZ,IAAIoP,EAAW,yBAGXqH,EAAiB,8BAsBjBpI,EAAS,CACXnc,UAAW,SACX4F,UAAW,EACXuH,SAAU,CACR,CAAExH,MAAO,IAAKG,IAAK,KACnB,CAAEH,MAAO,IAAKG,IAAK,KACnB,CAAEH,MAAO,QAEX/O,SAAU,CACRkX,EAAKpI,iBAhBgB,CACvB1F,UAAW,oBACXmN,SAAU,CACR,CAAExH,MAAO,OAAQG,IAAK,QACtB,CAAEH,MAAO,MAAOG,IAAK,UAmBrB0e,EAAmB1W,EAAKvL,QAAQ4Z,EAAQ,CAC1ChP,SAAU,CACR,CAAExH,MAAO,IAAKG,IAAK,KACnB,CAAEH,MAAO,IAAKG,IAAK,KACnB,CAAEH,MAAO,mBAQT8e,EAAY,CACdzkB,UAAW,SACX2F,MAAO,iIAGLmZ,EAAkB,CACpBhZ,IAAK,IACLgH,gBAAgB,EAChB0H,YAAY,EACZjM,SAAU2U,EACVtX,UAAW,GAETmZ,EAAS,CACXpZ,MAAO,KACPG,IAAK,KACLlP,SAAU,CAACkoB,GACX/Y,QAAS,MACTH,UAAW,GAEToZ,EAAQ,CACVrZ,MAAO,MACPG,IAAK,MACLlP,SAAU,CAACkoB,GACX/Y,QAAS,MACTH,UAAW,GAGTmB,EAAQ,CAvEF,CACR/G,UAAW,OACXmN,SAAU,CACR,CAAExH,MAAO,gCACT,CAAEA,MAAO,kCACT,CAAEA,MAAO,oCAoEX,CACE3F,UAAW,OACX2F,MAAO,YACPC,UAAW,IAEb,CAKE5F,UAAW,SACX2F,MAAO,iEAET,CACEA,MAAO,WACPG,IAAK,UACL8M,YAAa,OACbsB,cAAc,EACdM,YAAY,EACZ5O,UAAW,GAEb,CACE5F,UAAW,OACX2F,MAAO,SAAW4e,GAGpB,CACEvkB,UAAW,OACX2F,MAAO,KAAO4e,EAAiB,KAEjC,CACEvkB,UAAW,OACX2F,MAAO,IAAM4e,GAEf,CACEvkB,UAAW,OACX2F,MAAO,KAAO4e,GAEhB,CACEvkB,UAAW,OACX2F,MAAO,IAAMmI,EAAKxI,oBAAsB,KAE1C,CACEtF,UAAW,OACX2F,MAAO,MAAQmI,EAAKxI,oBAAsB,KAE5C,CACEtF,UAAW,SAEX2F,MAAO,aACPC,UAAW,GAEbkI,EAAKxH,kBACL,CACE6B,cAAe+U,EACf3U,SAAU,CAAE+R,QAAS4C,IAEvBuH,EAGA,CACEzkB,UAAW,SACX2F,MAAOmI,EAAKtI,YAAc,MAC1BI,UAAW,GAEbmZ,EACAC,EACA7C,GAGEuI,EAAc,IAAI3d,GAKtB,OAJA2d,EAAY3gB,MACZ2gB,EAAYvuB,KAAKquB,GACjB1F,EAAgBloB,SAAW8tB,EAEpB,CACLhjB,KAAM,OACNsI,kBAAkB,EAClBqH,QAAS,CAAE,OACXza,SAAUmQ,EvB64Od,GwBxiPA,WACE,aAIAoK,GAAYqH,iBAAiB,WAAYgB,IACzCrI,GAAYqH,iBAAiB,OAAQqB,IACrC1I,GAAYqH,iBAAiB,MAAOwC,IACpC7J,GAAYqH,iBAAiB,OAAQiD,IACrCtK,GAAYqH,iBAAiB,aAAckD,IAC3CvK,GAAYqH,iBAAiB,MAAOmD,IACpCxK,GAAYqH,iBAAiB,SAAUoD,IACvCzK,GAAYqH,iBAAiB,SAAUwD,IACvC7K,GAAYqH,iBAAiB,OAAQ8D,IACrCnL,GAAYqH,iBAAiB,OAAQqE,IACrC1L,GAAYqH,iBAAiB,aAAa+E,IAC1CpM,GAAYqH,iBAAiB,OAAQmG,IACrCxN,GAAYqH,iBAAiB,SAAU4G,IACvCjO,GAAYqH,iBAAiB,WAAYsH,IACzC3O,GAAYqH,iBAAiB,MAAO4H,IACpCjP,GAAYqH,iBAAiB,aAAcgI,IAC3CrP,GAAYqH,iBAAiB,aAAc4I,IAC3CjQ,GAAYqH,iBAAiB,OAAQsJ,IACrC3Q,GAAYqH,iBAAiB,QAAS+J,IACtCpR,GAAYqH,iBAAiB,QAASoK,IACtCzR,GAAYqH,iBAAiB,MAAOwK,IACpC7R,GAAYqH,iBAAiB,MAAOsL,IACpC3S,GAAYqH,iBAAiB,OAAQ8L,IAErCnT,GAAYkH,UAAU,CAACsM,qBAAqB,IAE5C,IAAI,MAAMrlB,KAAehK,SAASkJ,iBAAiB,wBACjD2S,GAAYiH,eAAe9Y,EAG9B,CAnCD,E1BfA,CjCDA;C4DgBA,WACE,aAmCA,SAASslB,EAAkBC,GACzB,MAAMC,EAAcC,EAAsB,4BAE1C,OADAF,EAAeG,QAAQF,GAChBA,CCGT,CDAA,SAASG,EAAUC,EAAcJ,GAC/B,MAAMjlB,EAAQqlB,EAAa7mB,cAAc,UAAU6Y,YAC7CiO,EAAUD,EAAa1mB,iBAAiB,YAAY2W,KAAK,GACzDiQ,EAaR,SAAqB/vB,EAASgwB,EAAUC,GACtC,IAAIC,EAAUlwB,EAAQwB,mBACtB,KAAO0uB,GAAS,CACd,GAAIA,EAAQC,QAAQH,GAClB,OAAOE,EAET,GAAIA,EAAQC,QAAQF,GAClB,OAEFC,EAAUA,EAAQ1uB,kBCGpB,CACF,CD1BiB2Z,CAAY0U,EAAc,UAAW,iBAChDE,GACFD,EAAQM,OAAOL,GAEjB,MAAMM,EAAaX,EACjB,oBAAsBllB,EAAQ,UAKhC,OAHA6lB,EAAWC,QAAQC,UAAY/lB,EAC/BslB,EAAQQ,QAAQC,UAAY/lB,EAC5BilB,EAAYW,OAAOC,GACZ,CAAEA,WAAYA,EAAYP,QAASA,ECG5C,CDaA,SAASJ,EAAsB5M,GAC7B,MAAM0N,EAAWvwB,SAASyK,cAAc,YAExC,OADA8lB,EAAStvB,UAAY4hB,EACd0N,EAASV,QAAQ5U,UCG1B,CDAA,SAASuV,EAAmBC,GAC1B,IAAItvB,EAAYsvB,EAAiBC,uBACjC,KAAOvvB,IAAcA,EAAUE,UAAUC,SAAS,YAChDH,EAAYA,EAAUuvB,uBAExB,OAAOvvB,CCGT,CDUA,SAASwvB,EAAWC,GAClB,MAAMrmB,EAAQpH,KAAKye,YACnBzhB,OAAO0wB,aAAaC,QAAQF,EAAOrmB,GACnC,IAAK,MAAM6lB,KAAcpwB,SAASkJ,iBAAiB,QAC7C6nB,EAASX,KAAgBQ,GAASR,EAAWxO,cAAgBrX,GAC/DymB,EAAOZ,ECKb,CDAA,SAASY,EAAOZ,GACd,IAAK,MAAMphB,KAASohB,EAAWjnB,WAAWkF,SACxCW,EAAM3N,UAAUyI,OAAO,YAEzBsmB,EAAW/uB,UAAUG,IAAI,YACzB,IAAK,MAAMwN,KAASohB,EAAWjnB,WAAWA,WAAWkF,SAC/CW,EAAM3N,UAAUC,SAAS,aACvB8uB,EAAWC,QAAQC,YAActhB,EAAMqhB,QAAQC,UACjDthB,EAAM3N,UAAUyI,OAAO,UAEvBkF,EAAM3N,UAAUG,IAAI,UCM5B,CDAA,SAASuvB,EAASX,GAChB,MAAMa,EAAK,GACX,IAAKb,KAAcA,EAAWjnB,WAAWD,iBAAiB,QACxD+nB,EAAGpwB,KAAKuvB,EAAWxO,YAAY7N,eAEjC,OAAOkd,EAAGrQ,OAAOzR,KAAK,ICGxB,CD9HAhP,OAAOe,iBAAiB,QAExB,YAKA,WACE,IAAK,MAAMquB,KAAkBvvB,SAASkJ,iBAAiB,YAAa,CAClE,GAAIqmB,EAAexmB,cAAc,cAE/B,YADAtI,QAAQC,MAAM,+CAIJivB,EAAUJ,EADFD,EAAkBC,IAElCa,WAAW/uB,UAAUG,IAAI,YAC7B+tB,EAAexmB,cAAc,UAAUe,SACvCylB,EAAeluB,UAAUG,IAAI,eCG/B,CDDA,IAAK,MAAMivB,KAAoBzwB,SAASkJ,iBAAiB,cAAe,CACtE,MAAMqmB,EAAiBiB,EAAmBC,GAC1C,GAAIlB,EAAgB,CAClB,MACM2B,EAAMvB,EAAUc,EADFlB,EAAexmB,cAAc,UAEjDmoB,EAAIrB,QAAQxuB,UAAUG,IAAI,UAC1B+tB,EAAeY,OAAOe,EAAIrB,SAC1BY,EAAiB3mB,QCGnB,MDDErJ,QAAQG,MAAM,gDCIlB,CACF,ED9BEuwB,GA+EF,WACE,IAAK,MAAMf,KAAcpwB,SAASkJ,iBAAiB,QAAS,CAC1D,MAAM0nB,EAAQG,EAASX,GACvBA,EAAWlvB,iBAAiB,QAASyvB,EAAW/mB,KAAKwmB,EAAYQ,IAC7DR,EAAWxO,cAAgBzhB,OAAO0wB,aAAaO,QAAQR,IACzDI,EAAOZ,ECIX,CACF,CDxFEiB,ECGF,GDsHD,CAhID;C5DhBA,Wa8BA,IAAAC,EALA,SAAkBnvB,GAChB,IAAI8C,SAAc9C,EAClB,OAAgB,MAATA,IAA0B,UAAR8C,GAA4B,YAARA,EiDE/C,EAIIssB,EAAiB,CAAC,GACtB,SAAWjuB,IAAQ,WvDjCnB,IAAAC,EAAA,iBAAAD,GAAAA,GAAAA,EAAAE,SAAAA,QAAAF,EAEAiuB,EAAAhuB,CuDqCC,GAAEhB,KAAKY,KAAM,GAAEZ,KAAKY,KAAuB,oBAAXG,OAAyBA,OAAyB,oBAATG,KAAuBA,KAAyB,oBAAXtD,OAAyBA,OAAS,CAAC,GtDrClJ,IAAIuD,EAA0B,iBAARD,MAAoBA,MAAQA,KAAKD,SAAWA,QAAUC,KAK5E+tB,EAFWD,GAAc7tB,GAAYE,SAAS,cAATA,GuDgBrC6tB,EAJU,WACR,OAAOD,EAAKvqB,KAAKC,KDqDnB,EpCvEIO,EAAe,KAiBnB,IAAAiqB,EAPA,SAAyB9qB,GAGvB,IAFA,IAAI7D,EAAQ6D,EAAOtE,OAEZS,KAAW0E,EAAapB,KAAKO,EAAOe,OAAO5E,MAClD,OAAOA,CoC6ET,EnCzFI6E,EAAc,OAelB,IAAA+pB,EANA,SAAkB/qB,GAChB,OAAOA,EACHA,EAAOkB,MAAM,EAAG4pB,EAAgB9qB,GAAU,GAAGT,QAAQyB,EAAa,IAClEhB,CmCiGN,ErD3GA/C,EAFa2tB,EAAK1tB,OCAdC,EAAcP,OAAOQ,UAGrBC,EAAiBF,EAAYE,eAO7BC,EAAuBH,EAAYI,SAGnCC,EAAiBP,EAASA,EAAOQ,iBAAcpC,EA6BnD,IAAA2vB,EApBA,SAAmBzvB,GACjB,IAAIoC,EAAQN,EAAe1B,KAAKJ,EAAOiC,GACnCI,EAAMrC,EAAMiC,GAEhB,IACEjC,EAAMiC,QAAkBnC,EACxB,IAAIwC,GAAW,CACL,CAAV,MAAOC,GAAG,CAEZ,IAAIC,EAAST,EAAqB3B,KAAKJ,GAQvC,OAPIsC,IACEF,EACFpC,EAAMiC,GAAkBI,SAEjBrC,EAAMiC,IAGVO,CoD4HT,EnD9JIktB,EAPcruB,OAAOQ,UAOcG,SAavC,IAAA2tB,EAJA,SAAwB3vB,GACtB,OAAO0vB,EAAqBtvB,KAAKJ,EmD2KnC,ElDpLI4vB,EAAiBluB,EAASA,EAAOQ,iBAAcpC,EAkBnD,IAAA+vB,EATA,SAAoB7vB,GAClB,OAAa,MAATA,OACeF,IAAVE,EAdQ,qBADL,gBAiBJ4vB,GAAkBA,KAAkBvuB,OAAOrB,GAC/CyvB,EAAUzvB,GACV2vB,EAAe3vB,EkDgMrB,ElC5LA,IAAA8vB,EAJA,SAAsB9vB,GACpB,OAAgB,MAATA,GAAiC,iBAATA,CkC6NjC,EjC1NA,IAAA+vB,EALA,SAAkB/vB,GAChB,MAAuB,iBAATA,GACX8vB,EAAa9vB,IArBF,mBAqBY6vB,EAAW7vB,EiC0PvC,EhC3QI8F,EAAa,qBAGbC,EAAa,aAGbC,EAAY,cAGZC,EAAeC,SA8CnB,IAAA8pB,EArBA,SAAkBhwB,GAChB,GAAoB,iBAATA,EACT,OAAOA,EAET,GAAI+vB,EAAS/vB,GACX,OA1CM,IA4CR,GAAImvB,EAASnvB,GAAQ,CACnB,IAAIoG,EAAgC,mBAAjBpG,EAAMqG,QAAwBrG,EAAMqG,UAAYrG,EACnEA,EAAQmvB,EAAS/oB,GAAUA,EAAQ,GAAMA,CgCsR3C,ChCpRA,GAAoB,iBAATpG,EACT,OAAiB,IAAVA,EAAcA,GAASA,EAEhCA,EAAQwvB,EAASxvB,GACjB,IAAIsG,EAAWP,EAAW7B,KAAKlE,GAC/B,OAAQsG,GAAYN,EAAU9B,KAAKlE,GAC/BiG,EAAajG,EAAM2F,MAAM,GAAIW,EAAW,EAAI,GAC3CR,EAAW5B,KAAKlE,GAvDb,KAuD6BA,CgCsRvC,EE1UIK,EAAYC,KAAKC,IACjB0vB,EAAY3vB,KAAK4vB,IAqLrB,IAAAC,EA7HA,SAAkB3wB,EAAMC,EAAM8L,GAC5B,IAAI6kB,EACAC,EACAC,EACA9tB,EACA+tB,EACAC,EACAC,EAAiB,EACjBC,GAAU,EACVC,GAAS,EACTC,GAAW,EAEf,GAAmB,mBAARpxB,EACT,MAAM,IAAIG,UAzEQ,uBAmFpB,SAASkxB,EAAWC,GAClB,IAAIpxB,EAAO0wB,EACPlwB,EAAUmwB,EAKd,OAHAD,EAAWC,OAAWvwB,EACtB2wB,EAAiBK,EACjBtuB,EAAShD,EAAKK,MAAMK,EAASR,EFsV/B,CElVA,SAASqxB,EAAYD,GAMnB,OAJAL,EAAiBK,EAEjBP,EAAU3wB,WAAWoxB,EAAcvxB,GAE5BixB,EAAUG,EAAWC,GAAQtuB,CFqVtC,CExUA,SAASyuB,EAAaH,GACpB,IAAII,EAAoBJ,EAAON,EAM/B,YAAyB1wB,IAAjB0wB,GAA+BU,GAAqBzxB,GACzDyxB,EAAoB,GAAOP,GANJG,EAAOL,GAM8BH,CFqVjE,CElVA,SAASU,IACP,IAAIF,EAAOxB,IACX,GAAI2B,EAAaH,GACf,OAAOK,EAAaL,GAGtBP,EAAU3wB,WAAWoxB,EA3BvB,SAAuBF,GACrB,IAEIM,EAAc3xB,GAFMqxB,EAAON,GAI/B,OAAOG,EACHV,EAAUmB,EAAad,GAJDQ,EAAOL,IAK7BW,CFqVN,CEjUqCC,CAAcP,GFqVnD,CElVA,SAASK,EAAaL,GAKpB,OAJAP,OAAUzwB,EAIN8wB,GAAYR,EACPS,EAAWC,IAEpBV,EAAWC,OAAWvwB,EACf0C,EFqVT,CEtUA,SAAS8uB,IACP,IAAIR,EAAOxB,IACPiC,EAAaN,EAAaH,GAM9B,GAJAV,EAAWzvB,UACX0vB,EAAWrvB,KACXwvB,EAAeM,EAEXS,EAAY,CACd,QAAgBzxB,IAAZywB,EACF,OAAOQ,EAAYP,GAErB,GAAIG,EAIF,OAFAa,aAAajB,GACbA,EAAU3wB,WAAWoxB,EAAcvxB,GAC5BoxB,EAAWL,EFsVtB,CEhVA,YAHgB1wB,IAAZywB,IACFA,EAAU3wB,WAAWoxB,EAAcvxB,IAE9B+C,CFqVT,CEjVA,OA3GA/C,EAAOuwB,EAASvwB,IAAS,EACrB0vB,EAAS5jB,KACXmlB,IAAYnlB,EAAQmlB,QAEpBJ,GADAK,EAAS,YAAaplB,GACHlL,EAAU2vB,EAASzkB,EAAQ+kB,UAAY,EAAG7wB,GAAQ6wB,EACrEM,EAAW,aAAcrlB,IAAYA,EAAQqlB,SAAWA,GAoG1DU,EAAUG,OApCV,gBACkB3xB,IAAZywB,GACFiB,aAAajB,GAEfE,EAAiB,EACjBL,EAAWI,EAAeH,EAAWE,OAAUzwB,CFqVjD,EErTAwxB,EAAUI,MA7BV,WACE,YAAmB5xB,IAAZywB,EAAwB/tB,EAAS2uB,EAAa7B,IFqVvD,EExTOgC,CFqVT,EG5cA,IAAAK,EAlBA,SAAkBnyB,EAAMC,EAAM8L,GAC5B,IAAImlB,GAAU,EACVE,GAAW,EAEf,GAAmB,mBAARpxB,EACT,MAAM,IAAIG,UAnDQ,uBAyDpB,OAJIwvB,EAAS5jB,KACXmlB,EAAU,YAAanlB,IAAYA,EAAQmlB,QAAUA,EACrDE,EAAW,aAAcrlB,IAAYA,EAAQqlB,SAAWA,GAEnDT,EAAS3wB,EAAMC,EAAM,CAC1BixB,QAAWA,EACXJ,QAAW7wB,EACXmxB,SAAYA,GHqhBhB,GIrkBA,WACE,aAOA,IAAIgB,EACAC,EACAC,EAEAC,EACAC,EACAC,EAEAC,EAAuB,KACvBC,GAAkB,EAmFtB,SAASC,IACPC,IACA,MAAMC,EAAmBN,EAAuBO,IAAIv0B,OAAOC,SAASC,MAC9Ds0B,EAAiBC,EAAwBz0B,OAAOC,SAASC,MAC3Do0B,GAAoBI,EAAaF,KACnCL,GAAkB,EAClB5zB,EAAM,mCACNo0B,EAAmBL,EAAiBM,gBAEtCC,GJ2lBF,CIrrBA70B,OAAOe,iBAAiB,QAExB,WAIE,GAHA6yB,EAAa/zB,SAAS+I,cAAc,QACpCirB,EAAmBh0B,SAAS+I,cAAc,eAC1CkrB,EAAiBj0B,SAAS+I,cAAc,aACnCgrB,IAAeE,EAClB,OAEFC,EAYF,WACE,MAAMe,EAAkBC,IAClBC,EAAmB,GACzB,IACE,IAAIC,EAAe,EACnBA,GAAgBH,EAChBG,IAEAD,EAAiBt0B,KAAK,KAAOu0B,EAAe,GAAK,QAEnD,OAAOnB,EAAe/qB,iBAAiBisB,GAEvC,SAASD,IACP,IAAID,EAAkB,EACtB,IAAK,MAAMI,KAAetB,EAAW7qB,iBAAiB,KAAM,MAC1D+rB,EAAkBxyB,KAAKC,IACrBuyB,EACAK,EAAgBD,IAGpB,OAAOJ,CJ2lBT,CIxlBA,SAASK,EAAgBv1B,GACvB,IAAIq1B,EAAe,EACnB,KAAOr1B,GAAWA,IAAYg0B,GAC5BqB,GACuB,OAArBr1B,EAAQ2a,UAA0C,OAArB3a,EAAQ2a,SAAoB,EAAI,EAC/D3a,EAAUA,EAAQg1B,cAEpB,OAAOh1B,EAAUq1B,GAAgB,CJ2lBnC,CACF,CItoBoBG,GAClBpB,EA6CF,WACE,MAAMxvB,EAAS,IAAIgH,IACnB,IAAK,MAAM8oB,KAAoBV,EAAW7qB,iBAAiB,UAAW,CACpE,MAAMssB,EAAOf,EAAiBgB,aAAa,QACvCD,GACF7wB,EAAOmH,IAAI0pB,EAAMf,EJ4lBrB,CIzlBA,OAAO9vB,CJ2lBT,CIhpB2B+wB,GACzBtB,EAuDF,WACE,MAAMzvB,EAAS,IAAIgH,IACnB,IAAK,MAAMgpB,KAAkBT,EAAiB,CAC5C,MAAMsB,EAAOG,EAAmBhB,GAChC,GAAIa,EAAM,CACR,MAAMf,EAAmBN,EAAuBO,IAAIc,GACpD,GAAIf,EAAkB,CACpB,MAAMV,EAAaU,EAAiBM,cACpCpwB,EAAOmH,IAAI6oB,EAAgBZ,EJ2lB7B,CACF,CACF,CIzlBA,OAAOpvB,CJ2lBT,CI9pB+BixB,GAC7BrB,IACAp0B,OAAOe,iBAAiB,aAAcqzB,GACtCp0B,OAAOe,iBAAiB,SAAU20B,GAClC11B,OAAOe,iBAAiB,SAAU8zB,GAClC70B,OAAOe,iBAAiB,SAAU40B,GAClC/B,EAAW7yB,iBAAiB,QAAS60B,GACrC/B,EAAiB9yB,iBAAiB,QAAS80B,EJ2lB7C,IIhhBA,MAAMH,EAAW/B,GACf,WACEU,IACKF,GACH2B,GJ4lBJ,GIzlBA,GACA,CAAEpD,SAAS,IAGPmC,EAAc1C,GAAS,WAI3B,GAHA5xB,EAAM,mBACN8zB,IACAF,GAAkB,EACdD,EAAsB,CAGnBQ,EADkBD,EADVe,EAAmBtB,MAG9B4B,GJ4lBJ,MIzlBEA,GJ4lBJ,GI1lBG,IAEGH,EAAWhC,GACf,WACEU,GJ2lBF,GIzlBA,GACA,CAAE3B,SAAS,IAGb,SAASkD,EAAkBzb,GACzB,GAA8B,MAA1BA,EAAM4b,OAAOxb,SAAkB,CACjC,MAAMqa,EAAgBza,EAAM4b,OAAOnB,cACnC,GAAIA,GAAsC,kBAArBA,EAAc9D,GACjC,OAEFqD,GAAkB,EAClB5zB,EAAM,kCACNo0B,EAAmBxa,EAAM4b,OAAOnB,cJ2lBlC,CACF,CIxlBA,SAASiB,EAAiB1b,GACxBA,EAAM6b,kBACUn2B,SAASo2B,KAAK/0B,UAAU6I,OAAO,YAE7ClK,SAASq2B,gBAAgBn1B,iBAAiB,QAAS80B,GAEnDh2B,SAASq2B,gBAAgBC,oBAAoB,QAASN,EJ4lB1D,CIxlBA,SAASxB,IACP,MAAM+B,EAAgBp2B,OAAOq2B,iBAAiBx2B,SAASq2B,iBACjDI,EAAepuB,SACnBkuB,EAAcG,iBAAiB,0BAC/B,IAEEC,KAAYF,EACdz2B,SAASo2B,KAAK/0B,UAAUG,IAAI,aAE5BxB,SAASo2B,KAAK/0B,UAAUyI,OAAO,YJ4lBnC,CIxlBA,SAASmsB,IACPv1B,EAAM,iCACN,MAAMk2B,EAIR,WACE,MACMC,EADMF,IACgB,GAC5B,IAAK,IAAI5gB,EAAI,EAAGA,EAAIme,EAAgB5xB,SAAUyT,EAC5C,GAAIme,EAAgBne,GAAG+gB,UAAYD,EACjC,OAAO3C,EAAgBne,EAAI,GAAK,EAAIA,EAAI,EAAI,GAGhD,OAAOme,EAAgBA,EAAgB5xB,OAAS,EJ2lBlD,CIvmB4By0B,GAC1BjC,EAAmBV,EAA2BM,IAAIkC,GJ2lBpD,CI7kBA,SAAShC,EAAwBY,GAC/B,IAAK,IAAIzf,EAAI,EAAGA,EAAIme,EAAgB5xB,SAAUyT,EAC5C,GAAI4f,EAAmBzB,EAAgBne,MAAQyf,EAC7C,OAAOtB,EAAgBne,GAG3B,OAAO,IJ2lBT,CIxlBA,SAAS4f,EAAmB51B,GAC1B,MAAMi3B,EAAej3B,EAAQgJ,cAAc,WAC3C,OAAOiuB,EAAeA,EAAavB,aAAa,QAAU,IJ2lB5D,CIxlBA,SAASX,EAAmB/0B,GAC1B,GAAIA,GAAWA,IAAYs0B,EAKzB,IAJA3zB,EAAM,cAAgBX,EAAQ6hB,aAUhC,SAA8B7hB,GAC5B,GAAIA,EAEF,IADAA,EAAQsB,UAAUyI,OAAO,UAClB/J,EAAQg1B,eAAiBh1B,EAAQg1B,gBAAkBhB,GACxDh0B,EAAQg1B,cAAc1zB,UAAUyI,OAAO,YACvC/J,EAAUA,EAAQg1B,aJ6lBxB,CI3mBEkC,CAAqB5C,GACrBA,EAAuBt0B,EACvBA,EAAQsB,UAAUG,IAAI,UACfzB,EAAQg1B,eAAiBh1B,EAAQg1B,gBAAkBhB,GACxDh0B,EAAQg1B,cAAc1zB,UAAUG,IAAI,YACpCzB,EAAUA,EAAQg1B,aJumBxB,CIxlBA,SAAS4B,IACP,OAAO32B,SAASq2B,gBAAgBa,WAAal3B,SAASo2B,KAAKc,SJ2lB7D,CIxlBA,SAASrC,EAAa90B,GACpB,IAAKA,EACH,OAAO,EAET,MAAMo3B,EAAOp3B,EAAQq3B,wBACrB,OACED,EAAK5oB,KAAO,GACZ4oB,EAAKE,SACFl3B,OAAOm3B,aAAet3B,SAASq2B,gBAAgBkB,aJ4lBtD,CIxlBA,SAAS72B,EAAM4a,GArPG,KJm1BlB,CIzlBD,CAhQD,EjCfA,CjCDA","file":"site.js","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(function () {\n \"use strict\";\n\n window.addEventListener(\"load\", onChange);\n window.addEventListener(\"hashchange\", onChange);\n\n function onChange() {\n const element = document.getElementById(\"anchor-rewrite\");\n const anchor = window.location.hash.substr(1);\n if (element && anchor) {\n const rewites = JSON.parse(element.innerHTML);\n updateAnchor(anchor, rewites);\n }\n }\n\n function updateAnchor(anchor, rewrites) {\n const seen = [anchor];\n console.debug(anchor);\n while (rewrites[anchor]) {\n anchor = rewrites[anchor];\n if (seen.includes(anchor)) {\n console.error(\"Skipping circular anchor update\");\n return;\n }\n seen.push(anchor);\n }\n window.location.hash = anchor;\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(function () {\n \"use strict\";\n\n window.addEventListener(\"load\", onChange);\n window.addEventListener(\"hashchange\", onChange);\n\n function onChange() {\n const element = document.getElementById(\"anchor-rewrite\");\n const anchor = window.location.hash.substr(1);\n if (element && anchor) {\n const rewites = JSON.parse(element.innerHTML);\n updateAnchor(anchor, rewites);\n }\n }\n\n function updateAnchor(anchor, rewrites) {\n const seen = [anchor];\n console.debug(anchor);\n while (rewrites[anchor]) {\n anchor = rewrites[anchor];\n if (seen.includes(anchor)) {\n console.error(\"Skipping circular anchor update\");\n return;\n }\n seen.push(anchor);\n }\n window.location.hash = anchor;\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(function () {\n \"use strict\";\n\n markLastAuthor();\n\n function markLastAuthor() {\n let candidate = document.getElementById(\"author\");\n let lastAuthorElement = candidate;\n while (candidate) {\n if (candidate.classList.contains(\"author\")) {\n lastAuthorElement = candidate;\n }\n candidate = candidate.nextElementSibling;\n }\n if (lastAuthorElement) {\n lastAuthorElement.classList.add(\"last-author\");\n }\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(function () {\n \"use strict\";\n\n markLastAuthor();\n\n function markLastAuthor() {\n let candidate = document.getElementById(\"author\");\n let lastAuthorElement = candidate;\n while (candidate) {\n if (candidate.classList.contains(\"author\")) {\n lastAuthorElement = candidate;\n }\n candidate = candidate.nextElementSibling;\n }\n if (lastAuthorElement) {\n lastAuthorElement.classList.add(\"last-author\");\n }\n }\n})();\n","(function(){\n","/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\nfunction baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n}\n\nmodule.exports = baseDelay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n addCodeToolElements();\n\n function addCodeToolElements() {\n for (const preElement of document.querySelectorAll(\".doc pre.highlight\")) {\n const codeToolsElement = document.createElement(\"div\");\n codeToolsElement.className = \"codetools\";\n if (addButtons(preElement, codeToolsElement)) {\n preElement.appendChild(codeToolsElement);\n }\n }\n\n function addButtons(preElement, codeToolsElement) {\n let numberOfButtons = 0;\n if (hasHideWhenFoldedSpans(preElement)) {\n addFoldUnfoldButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n if (window.navigator.clipboard) {\n addCopyButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n return numberOfButtons > 0;\n }\n\n function hasHideWhenFoldedSpans(preElement) {\n return !!preElement.querySelector(\"span.hide-when-folded\");\n }\n\n function addFoldUnfoldButton(preElement, codeToolsElement) {\n const foldUnfoldButton = createButton();\n updateFoldUnfoldButton(foldUnfoldButton, true);\n foldUnfoldButton.addEventListener(\n \"click\",\n onFoldUnfoldButtonClick.bind(foldUnfoldButton, preElement)\n );\n codeToolsElement.appendChild(foldUnfoldButton);\n }\n\n function addCopyButton(preElement, codeToolsElement) {\n const copyButton = createButton(\"Copy to clipboard\", \"copy-button\");\n copyButton.addEventListener(\n \"click\",\n onCopyButtonClick.bind(copyButton, preElement)\n );\n copyButton.addEventListener(\"mouseleave\", clearClicked.bind(copyButton));\n copyButton.addEventListener(\"blur\", clearClicked.bind(copyButton));\n const copiedPopup = document.createElement(\"span\");\n copyButton.appendChild(copiedPopup);\n copiedPopup.className = \"copied\";\n codeToolsElement.appendChild(copyButton);\n }\n\n function createButton(label, className) {\n const buttonElement = document.createElement(\"button\");\n buttonElement.className = className;\n buttonElement.title = label;\n buttonElement.type = \"button\";\n const labelElement = document.createElement(\"span\");\n labelElement.appendChild(document.createTextNode(label));\n labelElement.className = \"label\";\n buttonElement.appendChild(labelElement);\n return buttonElement;\n }\n }\n\n function onCopyButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const copy = codeElement.cloneNode(true);\n for (const hideWhenFoldedElement of copy.querySelectorAll(\n \".hide-when-unfolded\"\n )) {\n hideWhenFoldedElement.parentNode.removeChild(hideWhenFoldedElement);\n }\n const text = copy.innerText;\n if (text) {\n window.navigator.clipboard\n .writeText(text + \"\\n\")\n .then(markClicked.bind(this));\n }\n }\n\n function markClicked() {\n this.classList.add(\"clicked\");\n }\n\n function clearClicked() {\n this.classList.remove(\"clicked\");\n }\n\n function onFoldUnfoldButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const unfolding = !codeElement.classList.contains(\"unfolded\");\n codeElement.classList.remove(unfolding ? \"folding\" : \"unfolding\");\n codeElement.classList.add(unfolding ? \"unfolding\" : \"folding\");\n delay(function () {\n codeElement.classList.remove(unfolding ? \"unfolding\" : \"folding\");\n codeElement.classList.toggle(\"unfolded\");\n }, 1100);\n updateFoldUnfoldButton(this, !unfolding);\n }\n\n function updateFoldUnfoldButton(button, unfold) {\n const label = unfold ? \"Expand folded text\" : \"Collapse foldable text\";\n button.classList.remove(unfold ? \"fold-button\" : \"unfold-button\");\n button.classList.add(unfold ? \"unfold-button\" : \"fold-button\");\n button.querySelector(\"span.label\").innerText = label;\n button.title = label;\n }\n})();\n","/**\n * This method returns the first argument it receives.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Util\n * @param {*} value Any value.\n * @returns {*} Returns `value`.\n * @example\n *\n * var object = { 'a': 1 };\n *\n * console.log(_.identity(object) === object);\n * // => true\n */\nfunction identity(value) {\n return value;\n}\n\nmodule.exports = identity;\n","/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\nmodule.exports = apply;\n","var apply = require('./_apply');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\nfunction overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n}\n\nmodule.exports = overRest;\n","/**\n * Creates a function that returns `value`.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {*} value The value to return from the new function.\n * @returns {Function} Returns the new constant function.\n * @example\n *\n * var objects = _.times(2, _.constant({ 'a': 1 }));\n *\n * console.log(objects);\n * // => [{ 'a': 1 }, { 'a': 1 }]\n *\n * console.log(objects[0] === objects[1]);\n * // => true\n */\nfunction constant(value) {\n return function() {\n return value;\n };\n}\n\nmodule.exports = constant;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","var coreJsData = require('./_coreJsData');\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nmodule.exports = isMasked;\n","var root = require('./_root');\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\nmodule.exports = coreJsData;\n","/** Used for built-in method references. */\nvar funcProto = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nmodule.exports = toSource;\n","var isFunction = require('./isFunction'),\n isMasked = require('./_isMasked'),\n isObject = require('./isObject'),\n toSource = require('./_toSource');\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\nmodule.exports = baseIsNative;\n","/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\nmodule.exports = getValue;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var getNative = require('./_getNative');\n\nvar defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nmodule.exports = defineProperty;\n","var constant = require('./constant'),\n defineProperty = require('./_defineProperty'),\n identity = require('./identity');\n\n/**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n};\n\nmodule.exports = baseSetToString;\n","/** Used to detect hot functions by number of calls within a span of milliseconds. */\nvar HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeNow = Date.now;\n\n/**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\nfunction shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n}\n\nmodule.exports = shortOut;\n","var baseSetToString = require('./_baseSetToString'),\n shortOut = require('./_shortOut');\n\n/**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\nvar setToString = shortOut(baseSetToString);\n\nmodule.exports = setToString;\n","var identity = require('./identity'),\n overRest = require('./_overRest'),\n setToString = require('./_setToString');\n\n/**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\nfunction baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n}\n\nmodule.exports = baseRest;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n","var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","var baseDelay = require('./_baseDelay'),\n baseRest = require('./_baseRest'),\n toNumber = require('./toNumber');\n\n/**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\nvar delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n});\n\nmodule.exports = delay;\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(function () {\n \"use strict\";\n\n const delay = require(\"lodash/delay\");\n\n addCodeToolElements();\n\n function addCodeToolElements() {\n for (const preElement of document.querySelectorAll(\".doc pre.highlight\")) {\n const codeToolsElement = document.createElement(\"div\");\n codeToolsElement.className = \"codetools\";\n if (addButtons(preElement, codeToolsElement)) {\n preElement.appendChild(codeToolsElement);\n }\n }\n\n function addButtons(preElement, codeToolsElement) {\n let numberOfButtons = 0;\n if (hasHideWhenFoldedSpans(preElement)) {\n addFoldUnfoldButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n if (window.navigator.clipboard) {\n addCopyButton(preElement, codeToolsElement);\n numberOfButtons++;\n }\n return numberOfButtons > 0;\n }\n\n function hasHideWhenFoldedSpans(preElement) {\n return !!preElement.querySelector(\"span.hide-when-folded\");\n }\n\n function addFoldUnfoldButton(preElement, codeToolsElement) {\n const foldUnfoldButton = createButton();\n updateFoldUnfoldButton(foldUnfoldButton, true);\n foldUnfoldButton.addEventListener(\n \"click\",\n onFoldUnfoldButtonClick.bind(foldUnfoldButton, preElement)\n );\n codeToolsElement.appendChild(foldUnfoldButton);\n }\n\n function addCopyButton(preElement, codeToolsElement) {\n const copyButton = createButton(\"Copy to clipboard\", \"copy-button\");\n copyButton.addEventListener(\n \"click\",\n onCopyButtonClick.bind(copyButton, preElement)\n );\n copyButton.addEventListener(\"mouseleave\", clearClicked.bind(copyButton));\n copyButton.addEventListener(\"blur\", clearClicked.bind(copyButton));\n const copiedPopup = document.createElement(\"span\");\n copyButton.appendChild(copiedPopup);\n copiedPopup.className = \"copied\";\n codeToolsElement.appendChild(copyButton);\n }\n\n function createButton(label, className) {\n const buttonElement = document.createElement(\"button\");\n buttonElement.className = className;\n buttonElement.title = label;\n buttonElement.type = \"button\";\n const labelElement = document.createElement(\"span\");\n labelElement.appendChild(document.createTextNode(label));\n labelElement.className = \"label\";\n buttonElement.appendChild(labelElement);\n return buttonElement;\n }\n }\n\n function onCopyButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const copy = codeElement.cloneNode(true);\n for (const hideWhenFoldedElement of copy.querySelectorAll(\n \".hide-when-unfolded\"\n )) {\n hideWhenFoldedElement.parentNode.removeChild(hideWhenFoldedElement);\n }\n const text = copy.innerText;\n if (text) {\n window.navigator.clipboard\n .writeText(text + \"\\n\")\n .then(markClicked.bind(this));\n }\n }\n\n function markClicked() {\n this.classList.add(\"clicked\");\n }\n\n function clearClicked() {\n this.classList.remove(\"clicked\");\n }\n\n function onFoldUnfoldButtonClick(preElement) {\n const codeElement = preElement.querySelector(\"code\");\n const unfolding = !codeElement.classList.contains(\"unfolded\");\n codeElement.classList.remove(unfolding ? \"folding\" : \"unfolding\");\n codeElement.classList.add(unfolding ? \"unfolding\" : \"folding\");\n delay(function () {\n codeElement.classList.remove(unfolding ? \"unfolding\" : \"folding\");\n codeElement.classList.toggle(\"unfolded\");\n }, 1100);\n updateFoldUnfoldButton(this, !unfolding);\n }\n\n function updateFoldUnfoldButton(button, unfold) {\n const label = unfold ? \"Expand folded text\" : \"Collapse foldable text\";\n button.classList.remove(unfold ? \"fold-button\" : \"unfold-button\");\n button.classList.add(unfold ? \"unfold-button\" : \"fold-button\");\n button.querySelector(\"span.label\").innerText = label;\n button.title = label;\n }\n})();\n","\n}());","function deepFreeze(obj) {\n if (obj instanceof Map) {\n obj.clear = obj.delete = obj.set = function () {\n throw new Error('map is read-only');\n };\n } else if (obj instanceof Set) {\n obj.add = obj.clear = obj.delete = function () {\n throw new Error('set is read-only');\n };\n }\n\n // Freeze self\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach(function (name) {\n var prop = obj[name];\n\n // Freeze prop if it is an object\n if (typeof prop == 'object' && !Object.isFrozen(prop)) {\n deepFreeze(prop);\n }\n });\n\n return obj;\n}\n\nvar deepFreezeEs6 = deepFreeze;\nvar _default = deepFreeze;\ndeepFreezeEs6.default = _default;\n\n/** @implements CallbackResponse */\nclass Response {\n /**\n * @param {CompiledMode} mode\n */\n constructor(mode) {\n // eslint-disable-next-line no-undefined\n if (mode.data === undefined) mode.data = {};\n\n this.data = mode.data;\n this.isMatchIgnored = false;\n }\n\n ignoreMatch() {\n this.isMatchIgnored = true;\n }\n}\n\n/**\n * @param {string} value\n * @returns {string}\n */\nfunction escapeHTML(value) {\n return value\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * performs a shallow merge of multiple objects into one\n *\n * @template T\n * @param {T} original\n * @param {Record[]} objects\n * @returns {T} a single new object\n */\nfunction inherit(original, ...objects) {\n /** @type Record */\n const result = Object.create(null);\n\n for (const key in original) {\n result[key] = original[key];\n }\n objects.forEach(function(obj) {\n for (const key in obj) {\n result[key] = obj[key];\n }\n });\n return /** @type {T} */ (result);\n}\n\n/**\n * @typedef {object} Renderer\n * @property {(text: string) => void} addText\n * @property {(node: Node) => void} openNode\n * @property {(node: Node) => void} closeNode\n * @property {() => string} value\n */\n\n/** @typedef {{kind?: string, sublanguage?: boolean}} Node */\n/** @typedef {{walk: (r: Renderer) => void}} Tree */\n/** */\n\nconst SPAN_CLOSE = '
';\n\n/**\n * Determines if a node needs to be wrapped in \n *\n * @param {Node} node */\nconst emitsWrappingTags = (node) => {\n return !!node.kind;\n};\n\n/** @type {Renderer} */\nclass HTMLRenderer {\n /**\n * Creates a new HTMLRenderer\n *\n * @param {Tree} parseTree - the parse tree (must support `walk` API)\n * @param {{classPrefix: string}} options\n */\n constructor(parseTree, options) {\n this.buffer = \"\";\n this.classPrefix = options.classPrefix;\n parseTree.walk(this);\n }\n\n /**\n * Adds texts to the output stream\n *\n * @param {string} text */\n addText(text) {\n this.buffer += escapeHTML(text);\n }\n\n /**\n * Adds a node open to the output stream (if needed)\n *\n * @param {Node} node */\n openNode(node) {\n if (!emitsWrappingTags(node)) return;\n\n let className = node.kind;\n if (!node.sublanguage) {\n className = `${this.classPrefix}${className}`;\n }\n this.span(className);\n }\n\n /**\n * Adds a node close to the output stream (if needed)\n *\n * @param {Node} node */\n closeNode(node) {\n if (!emitsWrappingTags(node)) return;\n\n this.buffer += SPAN_CLOSE;\n }\n\n /**\n * returns the accumulated buffer\n */\n value() {\n return this.buffer;\n }\n\n // helpers\n\n /**\n * Builds a span element\n *\n * @param {string} className */\n span(className) {\n this.buffer += ``;\n }\n}\n\n/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} | string} Node */\n/** @typedef {{kind?: string, sublanguage?: boolean, children: Node[]} } DataNode */\n/** */\n\nclass TokenTree {\n constructor() {\n /** @type DataNode */\n this.rootNode = { children: [] };\n this.stack = [this.rootNode];\n }\n\n get top() {\n return this.stack[this.stack.length - 1];\n }\n\n get root() { return this.rootNode; }\n\n /** @param {Node} node */\n add(node) {\n this.top.children.push(node);\n }\n\n /** @param {string} kind */\n openNode(kind) {\n /** @type Node */\n const node = { kind, children: [] };\n this.add(node);\n this.stack.push(node);\n }\n\n closeNode() {\n if (this.stack.length > 1) {\n return this.stack.pop();\n }\n // eslint-disable-next-line no-undefined\n return undefined;\n }\n\n closeAllNodes() {\n while (this.closeNode());\n }\n\n toJSON() {\n return JSON.stringify(this.rootNode, null, 4);\n }\n\n /**\n * @typedef { import(\"./html_renderer\").Renderer } Renderer\n * @param {Renderer} builder\n */\n walk(builder) {\n // this does not\n return this.constructor._walk(builder, this.rootNode);\n // this works\n // return TokenTree._walk(builder, this.rootNode);\n }\n\n /**\n * @param {Renderer} builder\n * @param {Node} node\n */\n static _walk(builder, node) {\n if (typeof node === \"string\") {\n builder.addText(node);\n } else if (node.children) {\n builder.openNode(node);\n node.children.forEach((child) => this._walk(builder, child));\n builder.closeNode(node);\n }\n return builder;\n }\n\n /**\n * @param {Node} node\n */\n static _collapse(node) {\n if (typeof node === \"string\") return;\n if (!node.children) return;\n\n if (node.children.every(el => typeof el === \"string\")) {\n // node.text = node.children.join(\"\");\n // delete node.children;\n node.children = [node.children.join(\"\")];\n } else {\n node.children.forEach((child) => {\n TokenTree._collapse(child);\n });\n }\n }\n}\n\n/**\n Currently this is all private API, but this is the minimal API necessary\n that an Emitter must implement to fully support the parser.\n\n Minimal interface:\n\n - addKeyword(text, kind)\n - addText(text)\n - addSublanguage(emitter, subLanguageName)\n - finalize()\n - openNode(kind)\n - closeNode()\n - closeAllNodes()\n - toHTML()\n\n*/\n\n/**\n * @implements {Emitter}\n */\nclass TokenTreeEmitter extends TokenTree {\n /**\n * @param {*} options\n */\n constructor(options) {\n super();\n this.options = options;\n }\n\n /**\n * @param {string} text\n * @param {string} kind\n */\n addKeyword(text, kind) {\n if (text === \"\") { return; }\n\n this.openNode(kind);\n this.addText(text);\n this.closeNode();\n }\n\n /**\n * @param {string} text\n */\n addText(text) {\n if (text === \"\") { return; }\n\n this.add(text);\n }\n\n /**\n * @param {Emitter & {root: DataNode}} emitter\n * @param {string} name\n */\n addSublanguage(emitter, name) {\n /** @type DataNode */\n const node = emitter.root;\n node.kind = name;\n node.sublanguage = true;\n this.add(node);\n }\n\n toHTML() {\n const renderer = new HTMLRenderer(this, this.options);\n return renderer.value();\n }\n\n finalize() {\n return true;\n }\n}\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\nfunction escape(value) {\n return new RegExp(value.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&'), 'm');\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n if (!re) return null;\n if (typeof re === \"string\") return re;\n\n return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n const joined = args.map((x) => source(x)).join(\"\");\n return joined;\n}\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] } args\n * @returns {string}\n */\nfunction either(...args) {\n const joined = '(' + args.map((x) => source(x)).join(\"|\") + \")\";\n return joined;\n}\n\n/**\n * @param {RegExp} re\n * @returns {number}\n */\nfunction countMatchGroups(re) {\n return (new RegExp(re.toString() + '|')).exec('').length - 1;\n}\n\n/**\n * Does lexeme start with a regular expression match at the beginning\n * @param {RegExp} re\n * @param {string} lexeme\n */\nfunction startsWith(re, lexeme) {\n const match = re && re.exec(lexeme);\n return match && match.index === 0;\n}\n\n// BACKREF_RE matches an open parenthesis or backreference. To avoid\n// an incorrect parse, it additionally matches the following:\n// - [...] elements, where the meaning of parentheses and escapes change\n// - other escape sequences, so we do not misparse escape sequences as\n// interesting elements\n// - non-matching or lookahead parentheses, which do not capture. These\n// follow the '(' with a '?'.\nconst BACKREF_RE = /\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./;\n\n// join logically computes regexps.join(separator), but fixes the\n// backreferences so they continue to match.\n// it also places each individual regular expression into it's own\n// match group, keeping track of the sequencing of those match groups\n// is currently an exercise for the caller. :-)\n/**\n * @param {(string | RegExp)[]} regexps\n * @param {string} separator\n * @returns {string}\n */\nfunction join(regexps, separator = \"|\") {\n let numCaptures = 0;\n\n return regexps.map((regex) => {\n numCaptures += 1;\n const offset = numCaptures;\n let re = source(regex);\n let out = '';\n\n while (re.length > 0) {\n const match = BACKREF_RE.exec(re);\n if (!match) {\n out += re;\n break;\n }\n out += re.substring(0, match.index);\n re = re.substring(match.index + match[0].length);\n if (match[0][0] === '\\\\' && match[1]) {\n // Adjust the backreference.\n out += '\\\\' + String(Number(match[1]) + offset);\n } else {\n out += match[0];\n if (match[0] === '(') {\n numCaptures++;\n }\n }\n }\n return out;\n }).map(re => `(${re})`).join(separator);\n}\n\n// Common regexps\nconst MATCH_NOTHING_RE = /\\b\\B/;\nconst IDENT_RE = '[a-zA-Z]\\\\w*';\nconst UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\\\w*';\nconst NUMBER_RE = '\\\\b\\\\d+(\\\\.\\\\d+)?';\nconst C_NUMBER_RE = '(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)'; // 0x..., 0..., decimal, float\nconst BINARY_NUMBER_RE = '\\\\b(0b[01]+)'; // 0b...\nconst RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~';\n\n/**\n* @param { Partial & {binary?: string | RegExp} } opts\n*/\nconst SHEBANG = (opts = {}) => {\n const beginShebang = /^#![ ]*\\//;\n if (opts.binary) {\n opts.begin = concat(\n beginShebang,\n /.*\\b/,\n opts.binary,\n /\\b.*/);\n }\n return inherit({\n className: 'meta',\n begin: beginShebang,\n end: /$/,\n relevance: 0,\n /** @type {ModeCallback} */\n \"on:begin\": (m, resp) => {\n if (m.index !== 0) resp.ignoreMatch();\n }\n }, opts);\n};\n\n// Common modes\nconst BACKSLASH_ESCAPE = {\n begin: '\\\\\\\\[\\\\s\\\\S]', relevance: 0\n};\nconst APOS_STRING_MODE = {\n className: 'string',\n begin: '\\'',\n end: '\\'',\n illegal: '\\\\n',\n contains: [BACKSLASH_ESCAPE]\n};\nconst QUOTE_STRING_MODE = {\n className: 'string',\n begin: '\"',\n end: '\"',\n illegal: '\\\\n',\n contains: [BACKSLASH_ESCAPE]\n};\nconst PHRASAL_WORDS_MODE = {\n 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};\n/**\n * Creates a comment mode\n *\n * @param {string | RegExp} begin\n * @param {string | RegExp} end\n * @param {Mode | {}} [modeOptions]\n * @returns {Partial}\n */\nconst COMMENT = function(begin, end, modeOptions = {}) {\n const mode = inherit(\n {\n className: 'comment',\n begin,\n end,\n contains: []\n },\n modeOptions\n );\n mode.contains.push(PHRASAL_WORDS_MODE);\n mode.contains.push({\n className: 'doctag',\n begin: '(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):',\n relevance: 0\n });\n return mode;\n};\nconst C_LINE_COMMENT_MODE = COMMENT('//', '$');\nconst C_BLOCK_COMMENT_MODE = COMMENT('/\\\\*', '\\\\*/');\nconst HASH_COMMENT_MODE = COMMENT('#', '$');\nconst NUMBER_MODE = {\n className: 'number',\n begin: NUMBER_RE,\n relevance: 0\n};\nconst C_NUMBER_MODE = {\n className: 'number',\n begin: C_NUMBER_RE,\n relevance: 0\n};\nconst BINARY_NUMBER_MODE = {\n className: 'number',\n begin: BINARY_NUMBER_RE,\n relevance: 0\n};\nconst CSS_NUMBER_MODE = {\n className: 'number',\n begin: NUMBER_RE + '(' +\n '%|em|ex|ch|rem' +\n '|vw|vh|vmin|vmax' +\n '|cm|mm|in|pt|pc|px' +\n '|deg|grad|rad|turn' +\n '|s|ms' +\n '|Hz|kHz' +\n '|dpi|dpcm|dppx' +\n ')?',\n relevance: 0\n};\nconst REGEXP_MODE = {\n // this outer rule makes sure we actually have a WHOLE regex and not simply\n // an expression such as:\n //\n // 3 / something\n //\n // (which will then blow up when regex's `illegal` sees the newline)\n begin: /(?=\\/[^/\\n]*\\/)/,\n contains: [{\n className: 'regexp',\n begin: /\\//,\n end: /\\/[gimuy]*/,\n illegal: /\\n/,\n contains: [\n BACKSLASH_ESCAPE,\n {\n begin: /\\[/,\n end: /\\]/,\n relevance: 0,\n contains: [BACKSLASH_ESCAPE]\n }\n ]\n }]\n};\nconst TITLE_MODE = {\n className: 'title',\n begin: IDENT_RE,\n relevance: 0\n};\nconst UNDERSCORE_TITLE_MODE = {\n className: 'title',\n begin: UNDERSCORE_IDENT_RE,\n relevance: 0\n};\nconst METHOD_GUARD = {\n // excludes method names from keyword processing\n begin: '\\\\.\\\\s*' + UNDERSCORE_IDENT_RE,\n relevance: 0\n};\n\n/**\n * Adds end same as begin mechanics to a mode\n *\n * Your mode must include at least a single () match group as that first match\n * group is what is used for comparison\n * @param {Partial} mode\n */\nconst END_SAME_AS_BEGIN = function(mode) {\n return Object.assign(mode,\n {\n /** @type {ModeCallback} */\n 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },\n /** @type {ModeCallback} */\n 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }\n });\n};\n\nvar MODES = /*#__PURE__*/Object.freeze({\n __proto__: null,\n MATCH_NOTHING_RE: MATCH_NOTHING_RE,\n IDENT_RE: IDENT_RE,\n UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,\n NUMBER_RE: NUMBER_RE,\n C_NUMBER_RE: C_NUMBER_RE,\n BINARY_NUMBER_RE: BINARY_NUMBER_RE,\n RE_STARTERS_RE: RE_STARTERS_RE,\n SHEBANG: SHEBANG,\n BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,\n APOS_STRING_MODE: APOS_STRING_MODE,\n QUOTE_STRING_MODE: QUOTE_STRING_MODE,\n PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,\n COMMENT: COMMENT,\n C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,\n C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,\n HASH_COMMENT_MODE: HASH_COMMENT_MODE,\n NUMBER_MODE: NUMBER_MODE,\n C_NUMBER_MODE: C_NUMBER_MODE,\n BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,\n CSS_NUMBER_MODE: CSS_NUMBER_MODE,\n REGEXP_MODE: REGEXP_MODE,\n TITLE_MODE: TITLE_MODE,\n UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE,\n METHOD_GUARD: METHOD_GUARD,\n END_SAME_AS_BEGIN: END_SAME_AS_BEGIN\n});\n\n// Grammar extensions / plugins\n// See: https://github.com/highlightjs/highlight.js/issues/2833\n\n// Grammar extensions allow \"syntactic sugar\" to be added to the grammar modes\n// without requiring any underlying changes to the compiler internals.\n\n// `compileMatch` being the perfect small example of now allowing a grammar\n// author to write `match` when they desire to match a single expression rather\n// than being forced to use `begin`. The extension then just moves `match` into\n// `begin` when it runs. Ie, no features have been added, but we've just made\n// the experience of writing (and reading grammars) a little bit nicer.\n\n// ------\n\n// TODO: We need negative look-behind support to do this properly\n/**\n * Skip a match if it has a preceding dot\n *\n * This is used for `beginKeywords` to prevent matching expressions such as\n * `bob.keyword.do()`. The mode compiler automatically wires this up as a\n * special _internal_ 'on:begin' callback for modes with `beginKeywords`\n * @param {RegExpMatchArray} match\n * @param {CallbackResponse} response\n */\nfunction skipIfhasPrecedingDot(match, response) {\n const before = match.input[match.index - 1];\n if (before === \".\") {\n response.ignoreMatch();\n }\n}\n\n\n/**\n * `beginKeywords` syntactic sugar\n * @type {CompilerExt}\n */\nfunction beginKeywords(mode, parent) {\n if (!parent) return;\n if (!mode.beginKeywords) return;\n\n // for languages with keywords that include non-word characters checking for\n // a word boundary is not sufficient, so instead we check for a word boundary\n // or whitespace - this does no harm in any case since our keyword engine\n // doesn't allow spaces in keywords anyways and we still check for the boundary\n // first\n mode.begin = '\\\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\\\.)(?=\\\\b|\\\\s)';\n mode.__beforeBegin = skipIfhasPrecedingDot;\n mode.keywords = mode.keywords || mode.beginKeywords;\n delete mode.beginKeywords;\n\n // prevents double relevance, the keywords themselves provide\n // relevance, the mode doesn't need to double it\n // eslint-disable-next-line no-undefined\n if (mode.relevance === undefined) mode.relevance = 0;\n}\n\n/**\n * Allow `illegal` to contain an array of illegal values\n * @type {CompilerExt}\n */\nfunction compileIllegal(mode, _parent) {\n if (!Array.isArray(mode.illegal)) return;\n\n mode.illegal = either(...mode.illegal);\n}\n\n/**\n * `match` to match a single expression for readability\n * @type {CompilerExt}\n */\nfunction compileMatch(mode, _parent) {\n if (!mode.match) return;\n if (mode.begin || mode.end) throw new Error(\"begin & end are not supported with match\");\n\n mode.begin = mode.match;\n delete mode.match;\n}\n\n/**\n * provides the default 1 relevance to all modes\n * @type {CompilerExt}\n */\nfunction compileRelevance(mode, _parent) {\n // eslint-disable-next-line no-undefined\n if (mode.relevance === undefined) mode.relevance = 1;\n}\n\n// keywords that should have no default relevance value\nconst COMMON_KEYWORDS = [\n 'of',\n 'and',\n 'for',\n 'in',\n 'not',\n 'or',\n 'if',\n 'then',\n 'parent', // common variable name\n 'list', // common variable name\n 'value' // common variable name\n];\n\nconst DEFAULT_KEYWORD_CLASSNAME = \"keyword\";\n\n/**\n * Given raw keywords from a language definition, compile them.\n *\n * @param {string | Record | Array} rawKeywords\n * @param {boolean} caseInsensitive\n */\nfunction compileKeywords(rawKeywords, caseInsensitive, className = DEFAULT_KEYWORD_CLASSNAME) {\n /** @type KeywordDict */\n const compiledKeywords = {};\n\n // input can be a string of keywords, an array of keywords, or a object with\n // named keys representing className (which can then point to a string or array)\n if (typeof rawKeywords === 'string') {\n compileList(className, rawKeywords.split(\" \"));\n } else if (Array.isArray(rawKeywords)) {\n compileList(className, rawKeywords);\n } else {\n Object.keys(rawKeywords).forEach(function(className) {\n // collapse all our objects back into the parent object\n Object.assign(\n compiledKeywords,\n compileKeywords(rawKeywords[className], caseInsensitive, className)\n );\n });\n }\n return compiledKeywords;\n\n // ---\n\n /**\n * Compiles an individual list of keywords\n *\n * Ex: \"for if when while|5\"\n *\n * @param {string} className\n * @param {Array} keywordList\n */\n function compileList(className, keywordList) {\n if (caseInsensitive) {\n keywordList = keywordList.map(x => x.toLowerCase());\n }\n keywordList.forEach(function(keyword) {\n const pair = keyword.split('|');\n compiledKeywords[pair[0]] = [className, scoreForKeyword(pair[0], pair[1])];\n });\n }\n}\n\n/**\n * Returns the proper score for a given keyword\n *\n * Also takes into account comment keywords, which will be scored 0 UNLESS\n * another score has been manually assigned.\n * @param {string} keyword\n * @param {string} [providedScore]\n */\nfunction scoreForKeyword(keyword, providedScore) {\n // manual scores always win over common keywords\n // so you can force a score of 1 if you really insist\n if (providedScore) {\n return Number(providedScore);\n }\n\n return commonKeyword(keyword) ? 0 : 1;\n}\n\n/**\n * Determines if a given keyword is common or not\n *\n * @param {string} keyword */\nfunction commonKeyword(keyword) {\n return COMMON_KEYWORDS.includes(keyword.toLowerCase());\n}\n\n// compilation\n\n/**\n * Compiles a language definition result\n *\n * Given the raw result of a language definition (Language), compiles this so\n * that it is ready for highlighting code.\n * @param {Language} language\n * @param {{plugins: HLJSPlugin[]}} opts\n * @returns {CompiledLanguage}\n */\nfunction compileLanguage(language, { plugins }) {\n /**\n * Builds a regex with the case sensativility of the current language\n *\n * @param {RegExp | string} value\n * @param {boolean} [global]\n */\n function langRe(value, global) {\n return new RegExp(\n source(value),\n 'm' + (language.case_insensitive ? 'i' : '') + (global ? 'g' : '')\n );\n }\n\n /**\n Stores multiple regular expressions and allows you to quickly search for\n them all in a string simultaneously - returning the first match. It does\n this by creating a huge (a|b|c) regex - each individual item wrapped with ()\n and joined by `|` - using match groups to track position. When a match is\n found checking which position in the array has content allows us to figure\n out which of the original regexes / match groups triggered the match.\n\n The match object itself (the result of `Regex.exec`) is returned but also\n enhanced by merging in any meta-data that was registered with the regex.\n This is how we keep track of which mode matched, and what type of rule\n (`illegal`, `begin`, end, etc).\n */\n class MultiRegex {\n constructor() {\n this.matchIndexes = {};\n // @ts-ignore\n this.regexes = [];\n this.matchAt = 1;\n this.position = 0;\n }\n\n // @ts-ignore\n addRule(re, opts) {\n opts.position = this.position++;\n // @ts-ignore\n this.matchIndexes[this.matchAt] = opts;\n this.regexes.push([opts, re]);\n this.matchAt += countMatchGroups(re) + 1;\n }\n\n compile() {\n if (this.regexes.length === 0) {\n // avoids the need to check length every time exec is called\n // @ts-ignore\n this.exec = () => null;\n }\n const terminators = this.regexes.map(el => el[1]);\n this.matcherRe = langRe(join(terminators), true);\n this.lastIndex = 0;\n }\n\n /** @param {string} s */\n exec(s) {\n this.matcherRe.lastIndex = this.lastIndex;\n const match = this.matcherRe.exec(s);\n if (!match) { return null; }\n\n // eslint-disable-next-line no-undefined\n const i = match.findIndex((el, i) => i > 0 && el !== undefined);\n // @ts-ignore\n const matchData = this.matchIndexes[i];\n // trim off any earlier non-relevant match groups (ie, the other regex\n // match groups that make up the multi-matcher)\n match.splice(0, i);\n\n return Object.assign(match, matchData);\n }\n }\n\n /*\n Created to solve the key deficiently with MultiRegex - there is no way to\n test for multiple matches at a single location. Why would we need to do\n that? In the future a more dynamic engine will allow certain matches to be\n ignored. An example: if we matched say the 3rd regex in a large group but\n decided to ignore it - we'd need to started testing again at the 4th\n regex... but MultiRegex itself gives us no real way to do that.\n\n So what this class creates MultiRegexs on the fly for whatever search\n position they are needed.\n\n NOTE: These additional MultiRegex objects are created dynamically. For most\n grammars most of the time we will never actually need anything more than the\n first MultiRegex - so this shouldn't have too much overhead.\n\n Say this is our search group, and we match regex3, but wish to ignore it.\n\n regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0\n\n What we need is a new MultiRegex that only includes the remaining\n possibilities:\n\n regex4 | regex5 ' ie, startAt = 3\n\n This class wraps all that complexity up in a simple API... `startAt` decides\n where in the array of expressions to start doing the matching. It\n auto-increments, so if a match is found at position 2, then startAt will be\n set to 3. If the end is reached startAt will return to 0.\n\n MOST of the time the parser will be setting startAt manually to 0.\n */\n class ResumableMultiRegex {\n constructor() {\n // @ts-ignore\n this.rules = [];\n // @ts-ignore\n this.multiRegexes = [];\n this.count = 0;\n\n this.lastIndex = 0;\n this.regexIndex = 0;\n }\n\n // @ts-ignore\n getMatcher(index) {\n if (this.multiRegexes[index]) return this.multiRegexes[index];\n\n const matcher = new MultiRegex();\n this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));\n matcher.compile();\n this.multiRegexes[index] = matcher;\n return matcher;\n }\n\n resumingScanAtSamePosition() {\n return this.regexIndex !== 0;\n }\n\n considerAll() {\n this.regexIndex = 0;\n }\n\n // @ts-ignore\n addRule(re, opts) {\n this.rules.push([re, opts]);\n if (opts.type === \"begin\") this.count++;\n }\n\n /** @param {string} s */\n exec(s) {\n const m = this.getMatcher(this.regexIndex);\n m.lastIndex = this.lastIndex;\n let result = m.exec(s);\n\n // The following is because we have no easy way to say \"resume scanning at the\n // existing position but also skip the current rule ONLY\". What happens is\n // all prior rules are also skipped which can result in matching the wrong\n // thing. Example of matching \"booger\":\n\n // our matcher is [string, \"booger\", number]\n //\n // ....booger....\n\n // if \"booger\" is ignored then we'd really need a regex to scan from the\n // SAME position for only: [string, number] but ignoring \"booger\" (if it\n // was the first match), a simple resume would scan ahead who knows how\n // far looking only for \"number\", ignoring potential string matches (or\n // future \"booger\" matches that might be valid.)\n\n // So what we do: We execute two matchers, one resuming at the same\n // position, but the second full matcher starting at the position after:\n\n // /--- resume first regex match here (for [number])\n // |/---- full match here for [string, \"booger\", number]\n // vv\n // ....booger....\n\n // Which ever results in a match first is then used. So this 3-4 step\n // process essentially allows us to say \"match at this position, excluding\n // a prior rule that was ignored\".\n //\n // 1. Match \"booger\" first, ignore. Also proves that [string] does non match.\n // 2. Resume matching for [number]\n // 3. Match at index + 1 for [string, \"booger\", number]\n // 4. If #2 and #3 result in matches, which came first?\n if (this.resumingScanAtSamePosition()) {\n if (result && result.index === this.lastIndex) ; else { // use the second matcher result\n const m2 = this.getMatcher(0);\n m2.lastIndex = this.lastIndex + 1;\n result = m2.exec(s);\n }\n }\n\n if (result) {\n this.regexIndex += result.position + 1;\n if (this.regexIndex === this.count) {\n // wrap-around to considering all matches again\n this.considerAll();\n }\n }\n\n return result;\n }\n }\n\n /**\n * Given a mode, builds a huge ResumableMultiRegex that can be used to walk\n * the content and find matches.\n *\n * @param {CompiledMode} mode\n * @returns {ResumableMultiRegex}\n */\n function buildModeRegex(mode) {\n const mm = new ResumableMultiRegex();\n\n mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: \"begin\" }));\n\n if (mode.terminatorEnd) {\n mm.addRule(mode.terminatorEnd, { type: \"end\" });\n }\n if (mode.illegal) {\n mm.addRule(mode.illegal, { type: \"illegal\" });\n }\n\n return mm;\n }\n\n /** skip vs abort vs ignore\n *\n * @skip - The mode is still entered and exited normally (and contains rules apply),\n * but all content is held and added to the parent buffer rather than being\n * output when the mode ends. Mostly used with `sublanguage` to build up\n * a single large buffer than can be parsed by sublanguage.\n *\n * - The mode begin ands ends normally.\n * - Content matched is added to the parent mode buffer.\n * - The parser cursor is moved forward normally.\n *\n * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it\n * never matched) but DOES NOT continue to match subsequent `contains`\n * modes. Abort is bad/suboptimal because it can result in modes\n * farther down not getting applied because an earlier rule eats the\n * content but then aborts.\n *\n * - The mode does not begin.\n * - Content matched by `begin` is added to the mode buffer.\n * - The parser cursor is moved forward accordingly.\n *\n * @ignore - Ignores the mode (as if it never matched) and continues to match any\n * subsequent `contains` modes. Ignore isn't technically possible with\n * the current parser implementation.\n *\n * - The mode does not begin.\n * - Content matched by `begin` is ignored.\n * - The parser cursor is not moved forward.\n */\n\n /**\n * Compiles an individual mode\n *\n * This can raise an error if the mode contains certain detectable known logic\n * issues.\n * @param {Mode} mode\n * @param {CompiledMode | null} [parent]\n * @returns {CompiledMode | never}\n */\n function compileMode(mode, parent) {\n const cmode = /** @type CompiledMode */ (mode);\n if (mode.isCompiled) return cmode;\n\n [\n // do this early so compiler extensions generally don't have to worry about\n // the distinction between match/begin\n compileMatch\n ].forEach(ext => ext(mode, parent));\n\n language.compilerExtensions.forEach(ext => ext(mode, parent));\n\n // __beforeBegin is considered private API, internal use only\n mode.__beforeBegin = null;\n\n [\n beginKeywords,\n // do this later so compiler extensions that come earlier have access to the\n // raw array if they wanted to perhaps manipulate it, etc.\n compileIllegal,\n // default to 1 relevance if not specified\n compileRelevance\n ].forEach(ext => ext(mode, parent));\n\n mode.isCompiled = true;\n\n let keywordPattern = null;\n if (typeof mode.keywords === \"object\") {\n keywordPattern = mode.keywords.$pattern;\n delete mode.keywords.$pattern;\n }\n\n if (mode.keywords) {\n mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);\n }\n\n // both are not allowed\n if (mode.lexemes && keywordPattern) {\n throw new Error(\"ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) \");\n }\n\n // `mode.lexemes` was the old standard before we added and now recommend\n // using `keywords.$pattern` to pass the keyword pattern\n keywordPattern = keywordPattern || mode.lexemes || /\\w+/;\n cmode.keywordPatternRe = langRe(keywordPattern, true);\n\n if (parent) {\n if (!mode.begin) mode.begin = /\\B|\\b/;\n cmode.beginRe = langRe(mode.begin);\n if (mode.endSameAsBegin) mode.end = mode.begin;\n if (!mode.end && !mode.endsWithParent) mode.end = /\\B|\\b/;\n if (mode.end) cmode.endRe = langRe(mode.end);\n cmode.terminatorEnd = source(mode.end) || '';\n if (mode.endsWithParent && parent.terminatorEnd) {\n cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;\n }\n }\n if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));\n if (!mode.contains) mode.contains = [];\n\n mode.contains = [].concat(...mode.contains.map(function(c) {\n return expandOrCloneMode(c === 'self' ? mode : c);\n }));\n mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });\n\n if (mode.starts) {\n compileMode(mode.starts, parent);\n }\n\n cmode.matcher = buildModeRegex(cmode);\n return cmode;\n }\n\n if (!language.compilerExtensions) language.compilerExtensions = [];\n\n // self is not valid at the top-level\n if (language.contains && language.contains.includes('self')) {\n throw new Error(\"ERR: contains `self` is not supported at the top-level of a language. See documentation.\");\n }\n\n // we need a null object, which inherit will guarantee\n language.classNameAliases = inherit(language.classNameAliases || {});\n\n return compileMode(/** @type Mode */ (language));\n}\n\n/**\n * Determines if a mode has a dependency on it's parent or not\n *\n * If a mode does have a parent dependency then often we need to clone it if\n * it's used in multiple places so that each copy points to the correct parent,\n * where-as modes without a parent can often safely be re-used at the bottom of\n * a mode chain.\n *\n * @param {Mode | null} mode\n * @returns {boolean} - is there a dependency on the parent?\n * */\nfunction dependencyOnParent(mode) {\n if (!mode) return false;\n\n return mode.endsWithParent || dependencyOnParent(mode.starts);\n}\n\n/**\n * Expands a mode or clones it if necessary\n *\n * This is necessary for modes with parental dependenceis (see notes on\n * `dependencyOnParent`) and for nodes that have `variants` - which must then be\n * exploded into their own individual modes at compile time.\n *\n * @param {Mode} mode\n * @returns {Mode | Mode[]}\n * */\nfunction expandOrCloneMode(mode) {\n if (mode.variants && !mode.cachedVariants) {\n mode.cachedVariants = mode.variants.map(function(variant) {\n return inherit(mode, { variants: null }, variant);\n });\n }\n\n // EXPAND\n // if we have variants then essentially \"replace\" the mode with the variants\n // this happens in compileMode, where this function is called from\n if (mode.cachedVariants) {\n return mode.cachedVariants;\n }\n\n // CLONE\n // if we have dependencies on parents then we need a unique\n // instance of ourselves, so we can be reused with many\n // different parents without issue\n if (dependencyOnParent(mode)) {\n return inherit(mode, { starts: mode.starts ? inherit(mode.starts) : null });\n }\n\n if (Object.isFrozen(mode)) {\n return inherit(mode);\n }\n\n // no special dependency issues, just return ourselves\n return mode;\n}\n\nvar version = \"10.7.3\";\n\n// @ts-nocheck\n\nfunction hasValueOrEmptyAttribute(value) {\n return Boolean(value || value === \"\");\n}\n\nfunction BuildVuePlugin(hljs) {\n const Component = {\n props: [\"language\", \"code\", \"autodetect\"],\n data: function() {\n return {\n detectedLanguage: \"\",\n unknownLanguage: false\n };\n },\n computed: {\n className() {\n if (this.unknownLanguage) return \"\";\n\n return \"hljs \" + this.detectedLanguage;\n },\n highlighted() {\n // no idea what language to use, return raw code\n if (!this.autoDetect && !hljs.getLanguage(this.language)) {\n console.warn(`The language \"${this.language}\" you specified could not be found.`);\n this.unknownLanguage = true;\n return escapeHTML(this.code);\n }\n\n let result = {};\n if (this.autoDetect) {\n result = hljs.highlightAuto(this.code);\n this.detectedLanguage = result.language;\n } else {\n result = hljs.highlight(this.language, this.code, this.ignoreIllegals);\n this.detectedLanguage = this.language;\n }\n return result.value;\n },\n autoDetect() {\n return !this.language || hasValueOrEmptyAttribute(this.autodetect);\n },\n ignoreIllegals() {\n return true;\n }\n },\n // this avoids needing to use a whole Vue compilation pipeline just\n // to build Highlight.js\n render(createElement) {\n return createElement(\"pre\", {}, [\n createElement(\"code\", {\n class: this.className,\n domProps: { innerHTML: this.highlighted }\n })\n ]);\n }\n // template: `
`\n };\n\n const VuePlugin = {\n install(Vue) {\n Vue.component('highlightjs', Component);\n }\n };\n\n return { Component, VuePlugin };\n}\n\n/* plugin itself */\n\n/** @type {HLJSPlugin} */\nconst mergeHTMLPlugin = {\n \"after:highlightElement\": ({ el, result, text }) => {\n const originalStream = nodeStream(el);\n if (!originalStream.length) return;\n\n const resultNode = document.createElement('div');\n resultNode.innerHTML = result.value;\n result.value = mergeStreams(originalStream, nodeStream(resultNode), text);\n }\n};\n\n/* Stream merging support functions */\n\n/**\n * @typedef Event\n * @property {'start'|'stop'} event\n * @property {number} offset\n * @property {Node} node\n */\n\n/**\n * @param {Node} node\n */\nfunction tag(node) {\n return node.nodeName.toLowerCase();\n}\n\n/**\n * @param {Node} node\n */\nfunction nodeStream(node) {\n /** @type Event[] */\n const result = [];\n (function _nodeStream(node, offset) {\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === 3) {\n offset += child.nodeValue.length;\n } else if (child.nodeType === 1) {\n result.push({\n event: 'start',\n offset: offset,\n node: child\n });\n offset = _nodeStream(child, offset);\n // Prevent void elements from having an end tag that would actually\n // double them in the output. There are more void elements in HTML\n // but we list only those realistically expected in code display.\n if (!tag(child).match(/br|hr|img|input/)) {\n result.push({\n event: 'stop',\n offset: offset,\n node: child\n });\n }\n }\n }\n return offset;\n })(node, 0);\n return result;\n}\n\n/**\n * @param {any} original - the original stream\n * @param {any} highlighted - stream of the highlighted source\n * @param {string} value - the original source itself\n */\nfunction mergeStreams(original, highlighted, value) {\n let processed = 0;\n let result = '';\n const nodeStack = [];\n\n function selectStream() {\n if (!original.length || !highlighted.length) {\n return original.length ? original : highlighted;\n }\n if (original[0].offset !== highlighted[0].offset) {\n return (original[0].offset < highlighted[0].offset) ? original : highlighted;\n }\n\n /*\n To avoid starting the stream just before it should stop the order is\n ensured that original always starts first and closes last:\n\n if (event1 == 'start' && event2 == 'start')\n return original;\n if (event1 == 'start' && event2 == 'stop')\n return highlighted;\n if (event1 == 'stop' && event2 == 'start')\n return original;\n if (event1 == 'stop' && event2 == 'stop')\n return highlighted;\n\n ... which is collapsed to:\n */\n return highlighted[0].event === 'start' ? original : highlighted;\n }\n\n /**\n * @param {Node} node\n */\n function open(node) {\n /** @param {Attr} attr */\n function attributeString(attr) {\n return ' ' + attr.nodeName + '=\"' + escapeHTML(attr.value) + '\"';\n }\n // @ts-ignore\n result += '<' + tag(node) + [].map.call(node.attributes, attributeString).join('') + '>';\n }\n\n /**\n * @param {Node} node\n */\n function close(node) {\n result += '';\n }\n\n /**\n * @param {Event} event\n */\n function render(event) {\n (event.event === 'start' ? open : close)(event.node);\n }\n\n while (original.length || highlighted.length) {\n let stream = selectStream();\n result += escapeHTML(value.substring(processed, stream[0].offset));\n processed = stream[0].offset;\n if (stream === original) {\n /*\n On any opening or closing tag of the original markup we first close\n the entire highlighted node stack, then render the original tag along\n with all the following original tags at the same offset and then\n reopen all the tags on the highlighted stack.\n */\n nodeStack.reverse().forEach(close);\n do {\n render(stream.splice(0, 1)[0]);\n stream = selectStream();\n } while (stream === original && stream.length && stream[0].offset === processed);\n nodeStack.reverse().forEach(open);\n } else {\n if (stream[0].event === 'start') {\n nodeStack.push(stream[0].node);\n } else {\n nodeStack.pop();\n }\n render(stream.splice(0, 1)[0]);\n }\n }\n return result + escapeHTML(value.substr(processed));\n}\n\n/*\n\nFor the reasoning behind this please see:\nhttps://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419\n\n*/\n\n/**\n * @type {Record}\n */\nconst seenDeprecations = {};\n\n/**\n * @param {string} message\n */\nconst error = (message) => {\n console.error(message);\n};\n\n/**\n * @param {string} message\n * @param {any} args\n */\nconst warn = (message, ...args) => {\n console.log(`WARN: ${message}`, ...args);\n};\n\n/**\n * @param {string} version\n * @param {string} message\n */\nconst deprecated = (version, message) => {\n if (seenDeprecations[`${version}/${message}`]) return;\n\n console.log(`Deprecated as of ${version}. ${message}`);\n seenDeprecations[`${version}/${message}`] = true;\n};\n\n/*\nSyntax highlighting with language autodetection.\nhttps://highlightjs.org/\n*/\n\nconst escape$1 = escapeHTML;\nconst inherit$1 = inherit;\nconst NO_MATCH = Symbol(\"nomatch\");\n\n/**\n * @param {any} hljs - object that is extended (legacy)\n * @returns {HLJSApi}\n */\nconst HLJS = function(hljs) {\n // Global internal variables used within the highlight.js library.\n /** @type {Record} */\n const languages = Object.create(null);\n /** @type {Record} */\n const aliases = Object.create(null);\n /** @type {HLJSPlugin[]} */\n const plugins = [];\n\n // safe/production mode - swallows more errors, tries to keep running\n // even if a single syntax or parse hits a fatal error\n let SAFE_MODE = true;\n const fixMarkupRe = /(^(<[^>]+>|\\t|)+|\\n)/gm;\n const LANGUAGE_NOT_FOUND = \"Could not find the language '{}', did you forget to load/include a language module?\";\n /** @type {Language} */\n const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };\n\n // Global options used when within external APIs. This is modified when\n // calling the `hljs.configure` function.\n /** @type HLJSOptions */\n let options = {\n noHighlightRe: /^(no-?highlight)$/i,\n languageDetectRe: /\\blang(?:uage)?-([\\w-]+)\\b/i,\n classPrefix: 'hljs-',\n tabReplace: null,\n useBR: false,\n languages: null,\n // beta configuration options, subject to change, welcome to discuss\n // https://github.com/highlightjs/highlight.js/issues/1086\n __emitter: TokenTreeEmitter\n };\n\n /* Utility functions */\n\n /**\n * Tests a language name to see if highlighting should be skipped\n * @param {string} languageName\n */\n function shouldNotHighlight(languageName) {\n return options.noHighlightRe.test(languageName);\n }\n\n /**\n * @param {HighlightedHTMLElement} block - the HTML element to determine language for\n */\n function blockLanguage(block) {\n let classes = block.className + ' ';\n\n classes += block.parentNode ? block.parentNode.className : '';\n\n // language-* takes precedence over non-prefixed class names.\n const match = options.languageDetectRe.exec(classes);\n if (match) {\n const language = getLanguage(match[1]);\n if (!language) {\n warn(LANGUAGE_NOT_FOUND.replace(\"{}\", match[1]));\n warn(\"Falling back to no-highlight mode for this block.\", block);\n }\n return language ? match[1] : 'no-highlight';\n }\n\n return classes\n .split(/\\s+/)\n .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));\n }\n\n /**\n * Core highlighting function.\n *\n * OLD API\n * highlight(lang, code, ignoreIllegals, continuation)\n *\n * NEW API\n * highlight(code, {lang, ignoreIllegals})\n *\n * @param {string} codeOrlanguageName - the language to use for highlighting\n * @param {string | HighlightOptions} optionsOrCode - the code to highlight\n * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n * @param {CompiledMode} [continuation] - current continuation mode, if any\n *\n * @returns {HighlightResult} Result - an object that represents the result\n * @property {string} language - the language name\n * @property {number} relevance - the relevance score\n * @property {string} value - the highlighted HTML code\n * @property {string} code - the original raw code\n * @property {CompiledMode} top - top of the current mode stack\n * @property {boolean} illegal - indicates whether any illegal matches were found\n */\n function highlight(codeOrlanguageName, optionsOrCode, ignoreIllegals, continuation) {\n let code = \"\";\n let languageName = \"\";\n if (typeof optionsOrCode === \"object\") {\n code = codeOrlanguageName;\n ignoreIllegals = optionsOrCode.ignoreIllegals;\n languageName = optionsOrCode.language;\n // continuation not supported at all via the new API\n // eslint-disable-next-line no-undefined\n continuation = undefined;\n } else {\n // old API\n deprecated(\"10.7.0\", \"highlight(lang, code, ...args) has been deprecated.\");\n deprecated(\"10.7.0\", \"Please use highlight(code, options) instead.\\nhttps://github.com/highlightjs/highlight.js/issues/2277\");\n languageName = codeOrlanguageName;\n code = optionsOrCode;\n }\n\n /** @type {BeforeHighlightContext} */\n const context = {\n code,\n language: languageName\n };\n // the plugin can change the desired language or the code to be highlighted\n // just be changing the object it was passed\n fire(\"before:highlight\", context);\n\n // a before plugin can usurp the result completely by providing it's own\n // in which case we don't even need to call highlight\n const result = context.result\n ? context.result\n : _highlight(context.language, context.code, ignoreIllegals, continuation);\n\n result.code = context.code;\n // the plugin can change anything in result to suite it\n fire(\"after:highlight\", result);\n\n return result;\n }\n\n /**\n * private highlight that's used internally and does not fire callbacks\n *\n * @param {string} languageName - the language to use for highlighting\n * @param {string} codeToHighlight - the code to highlight\n * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n * @param {CompiledMode?} [continuation] - current continuation mode, if any\n * @returns {HighlightResult} - result of the highlight operation\n */\n function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {\n /**\n * Return keyword data if a match is a keyword\n * @param {CompiledMode} mode - current mode\n * @param {RegExpMatchArray} match - regexp match data\n * @returns {KeywordData | false}\n */\n function keywordData(mode, match) {\n const matchText = language.case_insensitive ? match[0].toLowerCase() : match[0];\n return Object.prototype.hasOwnProperty.call(mode.keywords, matchText) && mode.keywords[matchText];\n }\n\n function processKeywords() {\n if (!top.keywords) {\n emitter.addText(modeBuffer);\n return;\n }\n\n let lastIndex = 0;\n top.keywordPatternRe.lastIndex = 0;\n let match = top.keywordPatternRe.exec(modeBuffer);\n let buf = \"\";\n\n while (match) {\n buf += modeBuffer.substring(lastIndex, match.index);\n const data = keywordData(top, match);\n if (data) {\n const [kind, keywordRelevance] = data;\n emitter.addText(buf);\n buf = \"\";\n\n relevance += keywordRelevance;\n if (kind.startsWith(\"_\")) {\n // _ implied for relevance only, do not highlight\n // by applying a class name\n buf += match[0];\n } else {\n const cssClass = language.classNameAliases[kind] || kind;\n emitter.addKeyword(match[0], cssClass);\n }\n } else {\n buf += match[0];\n }\n lastIndex = top.keywordPatternRe.lastIndex;\n match = top.keywordPatternRe.exec(modeBuffer);\n }\n buf += modeBuffer.substr(lastIndex);\n emitter.addText(buf);\n }\n\n function processSubLanguage() {\n if (modeBuffer === \"\") return;\n /** @type HighlightResult */\n let result = null;\n\n if (typeof top.subLanguage === 'string') {\n if (!languages[top.subLanguage]) {\n emitter.addText(modeBuffer);\n return;\n }\n result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);\n continuations[top.subLanguage] = /** @type {CompiledMode} */ (result.top);\n } else {\n result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);\n }\n\n // Counting embedded language score towards the host language may be disabled\n // with zeroing the containing mode relevance. Use case in point is Markdown that\n // allows XML everywhere and makes every XML snippet to have a much larger Markdown\n // score.\n if (top.relevance > 0) {\n relevance += result.relevance;\n }\n emitter.addSublanguage(result.emitter, result.language);\n }\n\n function processBuffer() {\n if (top.subLanguage != null) {\n processSubLanguage();\n } else {\n processKeywords();\n }\n modeBuffer = '';\n }\n\n /**\n * @param {Mode} mode - new mode to start\n */\n function startNewMode(mode) {\n if (mode.className) {\n emitter.openNode(language.classNameAliases[mode.className] || mode.className);\n }\n top = Object.create(mode, { parent: { value: top } });\n return top;\n }\n\n /**\n * @param {CompiledMode } mode - the mode to potentially end\n * @param {RegExpMatchArray} match - the latest match\n * @param {string} matchPlusRemainder - match plus remainder of content\n * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode\n */\n function endOfMode(mode, match, matchPlusRemainder) {\n let matched = startsWith(mode.endRe, matchPlusRemainder);\n\n if (matched) {\n if (mode[\"on:end\"]) {\n const resp = new Response(mode);\n mode[\"on:end\"](match, resp);\n if (resp.isMatchIgnored) matched = false;\n }\n\n if (matched) {\n while (mode.endsParent && mode.parent) {\n mode = mode.parent;\n }\n return mode;\n }\n }\n // even if on:end fires an `ignore` it's still possible\n // that we might trigger the end node because of a parent mode\n if (mode.endsWithParent) {\n return endOfMode(mode.parent, match, matchPlusRemainder);\n }\n }\n\n /**\n * Handle matching but then ignoring a sequence of text\n *\n * @param {string} lexeme - string containing full match text\n */\n function doIgnore(lexeme) {\n if (top.matcher.regexIndex === 0) {\n // no more regexs to potentially match here, so we move the cursor forward one\n // space\n modeBuffer += lexeme[0];\n return 1;\n } else {\n // no need to move the cursor, we still have additional regexes to try and\n // match at this very spot\n resumeScanAtSamePosition = true;\n return 0;\n }\n }\n\n /**\n * Handle the start of a new potential mode match\n *\n * @param {EnhancedMatch} match - the current match\n * @returns {number} how far to advance the parse cursor\n */\n function doBeginMatch(match) {\n const lexeme = match[0];\n const newMode = match.rule;\n\n const resp = new Response(newMode);\n // first internal before callbacks, then the public ones\n const beforeCallbacks = [newMode.__beforeBegin, newMode[\"on:begin\"]];\n for (const cb of beforeCallbacks) {\n if (!cb) continue;\n cb(match, resp);\n if (resp.isMatchIgnored) return doIgnore(lexeme);\n }\n\n if (newMode && newMode.endSameAsBegin) {\n newMode.endRe = escape(lexeme);\n }\n\n if (newMode.skip) {\n modeBuffer += lexeme;\n } else {\n if (newMode.excludeBegin) {\n modeBuffer += lexeme;\n }\n processBuffer();\n if (!newMode.returnBegin && !newMode.excludeBegin) {\n modeBuffer = lexeme;\n }\n }\n startNewMode(newMode);\n // if (mode[\"after:begin\"]) {\n // let resp = new Response(mode);\n // mode[\"after:begin\"](match, resp);\n // }\n return newMode.returnBegin ? 0 : lexeme.length;\n }\n\n /**\n * Handle the potential end of mode\n *\n * @param {RegExpMatchArray} match - the current match\n */\n function doEndMatch(match) {\n const lexeme = match[0];\n const matchPlusRemainder = codeToHighlight.substr(match.index);\n\n const endMode = endOfMode(top, match, matchPlusRemainder);\n if (!endMode) { return NO_MATCH; }\n\n const origin = top;\n if (origin.skip) {\n modeBuffer += lexeme;\n } else {\n if (!(origin.returnEnd || origin.excludeEnd)) {\n modeBuffer += lexeme;\n }\n processBuffer();\n if (origin.excludeEnd) {\n modeBuffer = lexeme;\n }\n }\n do {\n if (top.className) {\n emitter.closeNode();\n }\n if (!top.skip && !top.subLanguage) {\n relevance += top.relevance;\n }\n top = top.parent;\n } while (top !== endMode.parent);\n if (endMode.starts) {\n if (endMode.endSameAsBegin) {\n endMode.starts.endRe = endMode.endRe;\n }\n startNewMode(endMode.starts);\n }\n return origin.returnEnd ? 0 : lexeme.length;\n }\n\n function processContinuations() {\n const list = [];\n for (let current = top; current !== language; current = current.parent) {\n if (current.className) {\n list.unshift(current.className);\n }\n }\n list.forEach(item => emitter.openNode(item));\n }\n\n /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */\n let lastMatch = {};\n\n /**\n * Process an individual match\n *\n * @param {string} textBeforeMatch - text preceeding the match (since the last match)\n * @param {EnhancedMatch} [match] - the match itself\n */\n function processLexeme(textBeforeMatch, match) {\n const lexeme = match && match[0];\n\n // add non-matched text to the current mode buffer\n modeBuffer += textBeforeMatch;\n\n if (lexeme == null) {\n processBuffer();\n return 0;\n }\n\n // we've found a 0 width match and we're stuck, so we need to advance\n // this happens when we have badly behaved rules that have optional matchers to the degree that\n // sometimes they can end up matching nothing at all\n // Ref: https://github.com/highlightjs/highlight.js/issues/2140\n if (lastMatch.type === \"begin\" && match.type === \"end\" && lastMatch.index === match.index && lexeme === \"\") {\n // spit the \"skipped\" character that our regex choked on back into the output sequence\n modeBuffer += codeToHighlight.slice(match.index, match.index + 1);\n if (!SAFE_MODE) {\n /** @type {AnnotatedError} */\n const err = new Error('0 width match regex');\n err.languageName = languageName;\n err.badRule = lastMatch.rule;\n throw err;\n }\n return 1;\n }\n lastMatch = match;\n\n if (match.type === \"begin\") {\n return doBeginMatch(match);\n } else if (match.type === \"illegal\" && !ignoreIllegals) {\n // illegal match, we do not continue processing\n /** @type {AnnotatedError} */\n const err = new Error('Illegal lexeme \"' + lexeme + '\" for mode \"' + (top.className || '') + '\"');\n err.mode = top;\n throw err;\n } else if (match.type === \"end\") {\n const processed = doEndMatch(match);\n if (processed !== NO_MATCH) {\n return processed;\n }\n }\n\n // edge case for when illegal matches $ (end of line) which is technically\n // a 0 width match but not a begin/end match so it's not caught by the\n // first handler (when ignoreIllegals is true)\n if (match.type === \"illegal\" && lexeme === \"\") {\n // advance so we aren't stuck in an infinite loop\n return 1;\n }\n\n // infinite loops are BAD, this is a last ditch catch all. if we have a\n // decent number of iterations yet our index (cursor position in our\n // parsing) still 3x behind our index then something is very wrong\n // so we bail\n if (iterations > 100000 && iterations > match.index * 3) {\n const err = new Error('potential infinite loop, way more iterations than matches');\n throw err;\n }\n\n /*\n Why might be find ourselves here? Only one occasion now. An end match that was\n triggered but could not be completed. When might this happen? When an `endSameasBegin`\n rule sets the end rule to a specific match. Since the overall mode termination rule that's\n being used to scan the text isn't recompiled that means that any match that LOOKS like\n the end (but is not, because it is not an exact match to the beginning) will\n end up here. A definite end match, but when `doEndMatch` tries to \"reapply\"\n the end rule and fails to match, we wind up here, and just silently ignore the end.\n\n This causes no real harm other than stopping a few times too many.\n */\n\n modeBuffer += lexeme;\n return lexeme.length;\n }\n\n const language = getLanguage(languageName);\n if (!language) {\n error(LANGUAGE_NOT_FOUND.replace(\"{}\", languageName));\n throw new Error('Unknown language: \"' + languageName + '\"');\n }\n\n const md = compileLanguage(language, { plugins });\n let result = '';\n /** @type {CompiledMode} */\n let top = continuation || md;\n /** @type Record */\n const continuations = {}; // keep continuations for sub-languages\n const emitter = new options.__emitter(options);\n processContinuations();\n let modeBuffer = '';\n let relevance = 0;\n let index = 0;\n let iterations = 0;\n let resumeScanAtSamePosition = false;\n\n try {\n top.matcher.considerAll();\n\n for (;;) {\n iterations++;\n if (resumeScanAtSamePosition) {\n // only regexes not matched previously will now be\n // considered for a potential match\n resumeScanAtSamePosition = false;\n } else {\n top.matcher.considerAll();\n }\n top.matcher.lastIndex = index;\n\n const match = top.matcher.exec(codeToHighlight);\n // console.log(\"match\", match[0], match.rule && match.rule.begin)\n\n if (!match) break;\n\n const beforeMatch = codeToHighlight.substring(index, match.index);\n const processedCount = processLexeme(beforeMatch, match);\n index = match.index + processedCount;\n }\n processLexeme(codeToHighlight.substr(index));\n emitter.closeAllNodes();\n emitter.finalize();\n result = emitter.toHTML();\n\n return {\n // avoid possible breakage with v10 clients expecting\n // this to always be an integer\n relevance: Math.floor(relevance),\n value: result,\n language: languageName,\n illegal: false,\n emitter: emitter,\n top: top\n };\n } catch (err) {\n if (err.message && err.message.includes('Illegal')) {\n return {\n illegal: true,\n illegalBy: {\n msg: err.message,\n context: codeToHighlight.slice(index - 100, index + 100),\n mode: err.mode\n },\n sofar: result,\n relevance: 0,\n value: escape$1(codeToHighlight),\n emitter: emitter\n };\n } else if (SAFE_MODE) {\n return {\n illegal: false,\n relevance: 0,\n value: escape$1(codeToHighlight),\n emitter: emitter,\n language: languageName,\n top: top,\n errorRaised: err\n };\n } else {\n throw err;\n }\n }\n }\n\n /**\n * returns a valid highlight result, without actually doing any actual work,\n * auto highlight starts with this and it's possible for small snippets that\n * auto-detection may not find a better match\n * @param {string} code\n * @returns {HighlightResult}\n */\n function justTextHighlightResult(code) {\n const result = {\n relevance: 0,\n emitter: new options.__emitter(options),\n value: escape$1(code),\n illegal: false,\n top: PLAINTEXT_LANGUAGE\n };\n result.emitter.addText(code);\n return result;\n }\n\n /**\n Highlighting with language detection. Accepts a string with the code to\n highlight. Returns an object with the following properties:\n\n - language (detected language)\n - relevance (int)\n - value (an HTML string with highlighting markup)\n - second_best (object with the same structure for second-best heuristically\n detected language, may be absent)\n\n @param {string} code\n @param {Array} [languageSubset]\n @returns {AutoHighlightResult}\n */\n function highlightAuto(code, languageSubset) {\n languageSubset = languageSubset || options.languages || Object.keys(languages);\n const plaintext = justTextHighlightResult(code);\n\n const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>\n _highlight(name, code, false)\n );\n results.unshift(plaintext); // plaintext is always an option\n\n const sorted = results.sort((a, b) => {\n // sort base on relevance\n if (a.relevance !== b.relevance) return b.relevance - a.relevance;\n\n // always award the tie to the base language\n // ie if C++ and Arduino are tied, it's more likely to be C++\n if (a.language && b.language) {\n if (getLanguage(a.language).supersetOf === b.language) {\n return 1;\n } else if (getLanguage(b.language).supersetOf === a.language) {\n return -1;\n }\n }\n\n // otherwise say they are equal, which has the effect of sorting on\n // relevance while preserving the original ordering - which is how ties\n // have historically been settled, ie the language that comes first always\n // wins in the case of a tie\n return 0;\n });\n\n const [best, secondBest] = sorted;\n\n /** @type {AutoHighlightResult} */\n const result = best;\n result.second_best = secondBest;\n\n return result;\n }\n\n /**\n Post-processing of the highlighted markup:\n\n - replace TABs with something more useful\n - replace real line-breaks with '
' for non-pre containers\n\n @param {string} html\n @returns {string}\n */\n function fixMarkup(html) {\n if (!(options.tabReplace || options.useBR)) {\n return html;\n }\n\n return html.replace(fixMarkupRe, match => {\n if (match === '\\n') {\n return options.useBR ? '
' : match;\n } else if (options.tabReplace) {\n return match.replace(/\\t/g, options.tabReplace);\n }\n return match;\n });\n }\n\n /**\n * Builds new class name for block given the language name\n *\n * @param {HTMLElement} element\n * @param {string} [currentLang]\n * @param {string} [resultLang]\n */\n function updateClassName(element, currentLang, resultLang) {\n const language = currentLang ? aliases[currentLang] : resultLang;\n\n element.classList.add(\"hljs\");\n if (language) element.classList.add(language);\n }\n\n /** @type {HLJSPlugin} */\n const brPlugin = {\n \"before:highlightElement\": ({ el }) => {\n if (options.useBR) {\n el.innerHTML = el.innerHTML.replace(/\\n/g, '').replace(//g, '\\n');\n }\n },\n \"after:highlightElement\": ({ result }) => {\n if (options.useBR) {\n result.value = result.value.replace(/\\n/g, \"
\");\n }\n }\n };\n\n const TAB_REPLACE_RE = /^(<[^>]+>|\\t)+/gm;\n /** @type {HLJSPlugin} */\n const tabReplacePlugin = {\n \"after:highlightElement\": ({ result }) => {\n if (options.tabReplace) {\n result.value = result.value.replace(TAB_REPLACE_RE, (m) =>\n m.replace(/\\t/g, options.tabReplace)\n );\n }\n }\n };\n\n /**\n * Applies highlighting to a DOM node containing code. Accepts a DOM node and\n * two optional parameters for fixMarkup.\n *\n * @param {HighlightedHTMLElement} element - the HTML element to highlight\n */\n function highlightElement(element) {\n /** @type HTMLElement */\n let node = null;\n const language = blockLanguage(element);\n\n if (shouldNotHighlight(language)) return;\n\n // support for v10 API\n fire(\"before:highlightElement\",\n { el: element, language: language });\n\n node = element;\n const text = node.textContent;\n const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);\n\n // support for v10 API\n fire(\"after:highlightElement\", { el: element, result, text });\n\n element.innerHTML = result.value;\n updateClassName(element, language, result.language);\n element.result = {\n language: result.language,\n // TODO: remove with version 11.0\n re: result.relevance,\n relavance: result.relevance\n };\n if (result.second_best) {\n element.second_best = {\n language: result.second_best.language,\n // TODO: remove with version 11.0\n re: result.second_best.relevance,\n relavance: result.second_best.relevance\n };\n }\n }\n\n /**\n * Updates highlight.js global options with the passed options\n *\n * @param {Partial} userOptions\n */\n function configure(userOptions) {\n if (userOptions.useBR) {\n deprecated(\"10.3.0\", \"'useBR' will be removed entirely in v11.0\");\n deprecated(\"10.3.0\", \"Please see https://github.com/highlightjs/highlight.js/issues/2559\");\n }\n options = inherit$1(options, userOptions);\n }\n\n /**\n * Highlights to all
 blocks on a page\n   *\n   * @type {Function & {called?: boolean}}\n   */\n  // TODO: remove v12, deprecated\n  const initHighlighting = () => {\n    if (initHighlighting.called) return;\n    initHighlighting.called = true;\n\n    deprecated(\"10.6.0\", \"initHighlighting() is deprecated.  Use highlightAll() instead.\");\n\n    const blocks = document.querySelectorAll('pre code');\n    blocks.forEach(highlightElement);\n  };\n\n  // Higlights all when DOMContentLoaded fires\n  // TODO: remove v12, deprecated\n  function initHighlightingOnLoad() {\n    deprecated(\"10.6.0\", \"initHighlightingOnLoad() is deprecated.  Use highlightAll() instead.\");\n    wantsHighlight = true;\n  }\n\n  let wantsHighlight = false;\n\n  /**\n   * auto-highlights all pre>code elements on the page\n   */\n  function highlightAll() {\n    // if we are called too early in the loading process\n    if (document.readyState === \"loading\") {\n      wantsHighlight = true;\n      return;\n    }\n\n    const blocks = document.querySelectorAll('pre code');\n    blocks.forEach(highlightElement);\n  }\n\n  function boot() {\n    // if a highlight was requested before DOM was loaded, do now\n    if (wantsHighlight) highlightAll();\n  }\n\n  // make sure we are in the browser environment\n  if (typeof window !== 'undefined' && window.addEventListener) {\n    window.addEventListener('DOMContentLoaded', boot, false);\n  }\n\n  /**\n   * Register a language grammar module\n   *\n   * @param {string} languageName\n   * @param {LanguageFn} languageDefinition\n   */\n  function registerLanguage(languageName, languageDefinition) {\n    let lang = null;\n    try {\n      lang = languageDefinition(hljs);\n    } catch (error$1) {\n      error(\"Language definition for '{}' could not be registered.\".replace(\"{}\", languageName));\n      // hard or soft error\n      if (!SAFE_MODE) { throw error$1; } else { error(error$1); }\n      // languages that have serious errors are replaced with essentially a\n      // \"plaintext\" stand-in so that the code blocks will still get normal\n      // css classes applied to them - and one bad language won't break the\n      // entire highlighter\n      lang = PLAINTEXT_LANGUAGE;\n    }\n    // give it a temporary name if it doesn't have one in the meta-data\n    if (!lang.name) lang.name = languageName;\n    languages[languageName] = lang;\n    lang.rawDefinition = languageDefinition.bind(null, hljs);\n\n    if (lang.aliases) {\n      registerAliases(lang.aliases, { languageName });\n    }\n  }\n\n  /**\n   * Remove a language grammar module\n   *\n   * @param {string} languageName\n   */\n  function unregisterLanguage(languageName) {\n    delete languages[languageName];\n    for (const alias of Object.keys(aliases)) {\n      if (aliases[alias] === languageName) {\n        delete aliases[alias];\n      }\n    }\n  }\n\n  /**\n   * @returns {string[]} List of language internal names\n   */\n  function listLanguages() {\n    return Object.keys(languages);\n  }\n\n  /**\n    intended usage: When one language truly requires another\n\n    Unlike `getLanguage`, this will throw when the requested language\n    is not available.\n\n    @param {string} name - name of the language to fetch/require\n    @returns {Language | never}\n  */\n  function requireLanguage(name) {\n    deprecated(\"10.4.0\", \"requireLanguage will be removed entirely in v11.\");\n    deprecated(\"10.4.0\", \"Please see https://github.com/highlightjs/highlight.js/pull/2844\");\n\n    const lang = getLanguage(name);\n    if (lang) { return lang; }\n\n    const err = new Error('The \\'{}\\' language is required, but not loaded.'.replace('{}', name));\n    throw err;\n  }\n\n  /**\n   * @param {string} name - name of the language to retrieve\n   * @returns {Language | undefined}\n   */\n  function getLanguage(name) {\n    name = (name || '').toLowerCase();\n    return languages[name] || languages[aliases[name]];\n  }\n\n  /**\n   *\n   * @param {string|string[]} aliasList - single alias or list of aliases\n   * @param {{languageName: string}} opts\n   */\n  function registerAliases(aliasList, { languageName }) {\n    if (typeof aliasList === 'string') {\n      aliasList = [aliasList];\n    }\n    aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });\n  }\n\n  /**\n   * Determines if a given language has auto-detection enabled\n   * @param {string} name - name of the language\n   */\n  function autoDetection(name) {\n    const lang = getLanguage(name);\n    return lang && !lang.disableAutodetect;\n  }\n\n  /**\n   * Upgrades the old highlightBlock plugins to the new\n   * highlightElement API\n   * @param {HLJSPlugin} plugin\n   */\n  function upgradePluginAPI(plugin) {\n    // TODO: remove with v12\n    if (plugin[\"before:highlightBlock\"] && !plugin[\"before:highlightElement\"]) {\n      plugin[\"before:highlightElement\"] = (data) => {\n        plugin[\"before:highlightBlock\"](\n          Object.assign({ block: data.el }, data)\n        );\n      };\n    }\n    if (plugin[\"after:highlightBlock\"] && !plugin[\"after:highlightElement\"]) {\n      plugin[\"after:highlightElement\"] = (data) => {\n        plugin[\"after:highlightBlock\"](\n          Object.assign({ block: data.el }, data)\n        );\n      };\n    }\n  }\n\n  /**\n   * @param {HLJSPlugin} plugin\n   */\n  function addPlugin(plugin) {\n    upgradePluginAPI(plugin);\n    plugins.push(plugin);\n  }\n\n  /**\n   *\n   * @param {PluginEvent} event\n   * @param {any} args\n   */\n  function fire(event, args) {\n    const cb = event;\n    plugins.forEach(function(plugin) {\n      if (plugin[cb]) {\n        plugin[cb](args);\n      }\n    });\n  }\n\n  /**\n  Note: fixMarkup is deprecated and will be removed entirely in v11\n\n  @param {string} arg\n  @returns {string}\n  */\n  function deprecateFixMarkup(arg) {\n    deprecated(\"10.2.0\", \"fixMarkup will be removed entirely in v11.0\");\n    deprecated(\"10.2.0\", \"Please see https://github.com/highlightjs/highlight.js/issues/2534\");\n\n    return fixMarkup(arg);\n  }\n\n  /**\n   *\n   * @param {HighlightedHTMLElement} el\n   */\n  function deprecateHighlightBlock(el) {\n    deprecated(\"10.7.0\", \"highlightBlock will be removed entirely in v12.0\");\n    deprecated(\"10.7.0\", \"Please use highlightElement now.\");\n\n    return highlightElement(el);\n  }\n\n  /* Interface definition */\n  Object.assign(hljs, {\n    highlight,\n    highlightAuto,\n    highlightAll,\n    fixMarkup: deprecateFixMarkup,\n    highlightElement,\n    // TODO: Remove with v12 API\n    highlightBlock: deprecateHighlightBlock,\n    configure,\n    initHighlighting,\n    initHighlightingOnLoad,\n    registerLanguage,\n    unregisterLanguage,\n    listLanguages,\n    getLanguage,\n    registerAliases,\n    requireLanguage,\n    autoDetection,\n    inherit: inherit$1,\n    addPlugin,\n    // plugins for frameworks\n    vuePlugin: BuildVuePlugin(hljs).VuePlugin\n  });\n\n  hljs.debugMode = function() { SAFE_MODE = false; };\n  hljs.safeMode = function() { SAFE_MODE = true; };\n  hljs.versionString = version;\n\n  for (const key in MODES) {\n    // @ts-ignore\n    if (typeof MODES[key] === \"object\") {\n      // @ts-ignore\n      deepFreezeEs6(MODES[key]);\n    }\n  }\n\n  // merge all the modes/regexs into our main object\n  Object.assign(hljs, MODES);\n\n  // built-in plugins, likely to be moved out of core in the future\n  hljs.addPlugin(brPlugin); // slated to be removed in v11\n  hljs.addPlugin(mergeHTMLPlugin);\n  hljs.addPlugin(tabReplacePlugin);\n  return hljs;\n};\n\n// export an \"instance\" of the highlighter\nvar highlight = HLJS({});\n\nmodule.exports = highlight;\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(function () {\n  'use strict';\n\n  const highlightJs = require('highlight.js/lib/core');\n\n  highlightJs.registerLanguage('asciidoc', require('highlight.js/lib/languages/asciidoc'));\n  highlightJs.registerLanguage('bash', require('highlight.js/lib/languages/bash'));\n  highlightJs.registerLanguage('css', require('highlight.js/lib/languages/css'));\n  highlightJs.registerLanguage('diff', require('highlight.js/lib/languages/diff'));\n  highlightJs.registerLanguage('dockerfile', require('highlight.js/lib/languages/dockerfile'));\n  highlightJs.registerLanguage('dos', require('highlight.js/lib/languages/dos'));\n  highlightJs.registerLanguage('gradle', require('highlight.js/lib/languages/gradle'));\n  highlightJs.registerLanguage('groovy', require('highlight.js/lib/languages/groovy'));\n  highlightJs.registerLanguage('http', require('highlight.js/lib/languages/http'));\n  highlightJs.registerLanguage('java', require('highlight.js/lib/languages/java'));\n  highlightJs.registerLanguage('javascript',require('highlight.js/lib/languages/javascript'));\n  highlightJs.registerLanguage('json', require('highlight.js/lib/languages/json'));\n  highlightJs.registerLanguage('kotlin', require('highlight.js/lib/languages/kotlin'));\n  highlightJs.registerLanguage('markdown', require('highlight.js/lib/languages/markdown'));\n  highlightJs.registerLanguage('nix', require('highlight.js/lib/languages/nix'));\n  highlightJs.registerLanguage('powershell', require('highlight.js/lib/languages/powershell'));\n  highlightJs.registerLanguage('properties', require('highlight.js/lib/languages/properties'));\n  highlightJs.registerLanguage('ruby', require('highlight.js/lib/languages/ruby'));\n  highlightJs.registerLanguage('scala', require('highlight.js/lib/languages/scala'));\n  highlightJs.registerLanguage('shell', require('highlight.js/lib/languages/shell'));\n  highlightJs.registerLanguage('sql', require('highlight.js/lib/languages/sql'));\n  highlightJs.registerLanguage('xml', require('highlight.js/lib/languages/xml'));\n  highlightJs.registerLanguage('yaml', require('highlight.js/lib/languages/yaml'));\n\n  highlightJs.configure({ignoreUnescapedHTML: true});\n\n  for(const codeElement of document.querySelectorAll('pre.highlight > code')) {\n    highlightJs.highlightBlock(codeElement);\n  }\n\n})();\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: AsciiDoc\nRequires: xml.js\nAuthor: Dan Allen \nWebsite: http://asciidoc.org\nDescription: A semantic, text-based document format that can be exported to HTML, DocBook and other backends.\nCategory: markup\n*/\n\n/** @type LanguageFn */\nfunction asciidoc(hljs) {\n  const HORIZONTAL_RULE = {\n    begin: '^\\'{3,}[ \\\\t]*$',\n    relevance: 10\n  };\n  const ESCAPED_FORMATTING = [\n    // escaped constrained formatting marks (i.e., \\* \\_ or \\`)\n    {\n      begin: /\\\\[*_`]/\n    },\n    // escaped unconstrained formatting marks (i.e., \\\\** \\\\__ or \\\\``)\n    // must ignore until the next formatting marks\n    // this rule might not be 100% compliant with Asciidoctor 2.0 but we are entering undefined behavior territory...\n    {\n      begin: /\\\\\\\\\\*{2}[^\\n]*?\\*{2}/\n    },\n    {\n      begin: /\\\\\\\\_{2}[^\\n]*_{2}/\n    },\n    {\n      begin: /\\\\\\\\`{2}[^\\n]*`{2}/\n    },\n    // guard: constrained formatting mark may not be preceded by \":\", \";\" or\n    // \"}\". match these so the constrained rule doesn't see them\n    {\n      begin: /[:;}][*_`](?![*_`])/\n    }\n  ];\n  const STRONG = [\n    // inline unconstrained strong (single line)\n    {\n      className: 'strong',\n      begin: /\\*{2}([^\\n]+?)\\*{2}/\n    },\n    // inline unconstrained strong (multi-line)\n    {\n      className: 'strong',\n      begin: concat(\n        /\\*\\*/,\n        /((\\*(?!\\*)|\\\\[^\\n]|[^*\\n\\\\])+\\n)+/,\n        /(\\*(?!\\*)|\\\\[^\\n]|[^*\\n\\\\])*/,\n        /\\*\\*/\n      ),\n      relevance: 0\n    },\n    // inline constrained strong (single line)\n    {\n      className: 'strong',\n      // must not precede or follow a word character\n      begin: /\\B\\*(\\S|\\S[^\\n]*?\\S)\\*(?!\\w)/\n    },\n    // inline constrained strong (multi-line)\n    {\n      className: 'strong',\n      // must not precede or follow a word character\n      begin: /\\*[^\\s]([^\\n]+\\n)+([^\\n]+)\\*/\n    }\n  ];\n  const EMPHASIS = [\n    // inline unconstrained emphasis (single line)\n    {\n      className: 'emphasis',\n      begin: /_{2}([^\\n]+?)_{2}/\n    },\n    // inline unconstrained emphasis (multi-line)\n    {\n      className: 'emphasis',\n      begin: concat(\n        /__/,\n        /((_(?!_)|\\\\[^\\n]|[^_\\n\\\\])+\\n)+/,\n        /(_(?!_)|\\\\[^\\n]|[^_\\n\\\\])*/,\n        /__/\n      ),\n      relevance: 0\n    },\n    // inline constrained emphasis (single line)\n    {\n      className: 'emphasis',\n      // must not precede or follow a word character\n      begin: /\\b_(\\S|\\S[^\\n]*?\\S)_(?!\\w)/\n    },\n    // inline constrained emphasis (multi-line)\n    {\n      className: 'emphasis',\n      // must not precede or follow a word character\n      begin: /_[^\\s]([^\\n]+\\n)+([^\\n]+)_/\n    },\n    // inline constrained emphasis using single quote (legacy)\n    {\n      className: 'emphasis',\n      // must not follow a word character or be followed by a single quote or space\n      begin: '\\\\B\\'(?![\\'\\\\s])',\n      end: '(\\\\n{2}|\\')',\n      // allow escaped single quote followed by word char\n      contains: [{\n        begin: '\\\\\\\\\\'\\\\w',\n        relevance: 0\n      }],\n      relevance: 0\n    }\n  ];\n  const ADMONITION = {\n    className: 'symbol',\n    begin: '^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\\\s+',\n    relevance: 10\n  };\n  const BULLET_LIST = {\n    className: 'bullet',\n    begin: '^(\\\\*+|-+|\\\\.+|[^\\\\n]+?::)\\\\s+'\n  };\n\n  return {\n    name: 'AsciiDoc',\n    aliases: ['adoc'],\n    contains: [\n      // block comment\n      hljs.COMMENT(\n        '^/{4,}\\\\n',\n        '\\\\n/{4,}$',\n        // can also be done as...\n        // '^/{4,}$',\n        // '^/{4,}$',\n        {\n          relevance: 10\n        }\n      ),\n      // line comment\n      hljs.COMMENT(\n        '^//',\n        '$',\n        {\n          relevance: 0\n        }\n      ),\n      // title\n      {\n        className: 'title',\n        begin: '^\\\\.\\\\w.*$'\n      },\n      // example, admonition & sidebar blocks\n      {\n        begin: '^[=\\\\*]{4,}\\\\n',\n        end: '\\\\n^[=\\\\*]{4,}$',\n        relevance: 10\n      },\n      // headings\n      {\n        className: 'section',\n        relevance: 10,\n        variants: [\n          {\n            begin: '^(={1,6})[ \\t].+?([ \\t]\\\\1)?$'\n          },\n          {\n            begin: '^[^\\\\[\\\\]\\\\n]+?\\\\n[=\\\\-~\\\\^\\\\+]{2,}$'\n          }\n        ]\n      },\n      // document attributes\n      {\n        className: 'meta',\n        begin: '^:.+?:',\n        end: '\\\\s',\n        excludeEnd: true,\n        relevance: 10\n      },\n      // block attributes\n      {\n        className: 'meta',\n        begin: '^\\\\[.+?\\\\]$',\n        relevance: 0\n      },\n      // quoteblocks\n      {\n        className: 'quote',\n        begin: '^_{4,}\\\\n',\n        end: '\\\\n_{4,}$',\n        relevance: 10\n      },\n      // listing and literal blocks\n      {\n        className: 'code',\n        begin: '^[\\\\-\\\\.]{4,}\\\\n',\n        end: '\\\\n[\\\\-\\\\.]{4,}$',\n        relevance: 10\n      },\n      // passthrough blocks\n      {\n        begin: '^\\\\+{4,}\\\\n',\n        end: '\\\\n\\\\+{4,}$',\n        contains: [{\n          begin: '<',\n          end: '>',\n          subLanguage: 'xml',\n          relevance: 0\n        }],\n        relevance: 10\n      },\n\n      BULLET_LIST,\n      ADMONITION,\n      ...ESCAPED_FORMATTING,\n      ...STRONG,\n      ...EMPHASIS,\n\n      // inline smart quotes\n      {\n        className: 'string',\n        variants: [\n          {\n            begin: \"``.+?''\"\n          },\n          {\n            begin: \"`.+?'\"\n          }\n        ]\n      },\n      // inline unconstrained emphasis\n      {\n        className: 'code',\n        begin: /`{2}/,\n        end: /(\\n{2}|`{2})/\n      },\n      // inline code snippets (TODO should get same treatment as strong and emphasis)\n      {\n        className: 'code',\n        begin: '(`.+?`|\\\\+.+?\\\\+)',\n        relevance: 0\n      },\n      // indented literal block\n      {\n        className: 'code',\n        begin: '^[ \\\\t]',\n        end: '$',\n        relevance: 0\n      },\n      HORIZONTAL_RULE,\n      // images and links\n      {\n        begin: '(link:)?(http|https|ftp|file|irc|image:?):\\\\S+?\\\\[[^[]*?\\\\]',\n        returnBegin: true,\n        contains: [\n          {\n            begin: '(link|image:?):',\n            relevance: 0\n          },\n          {\n            className: 'link',\n            begin: '\\\\w',\n            end: '[^\\\\[]+',\n            relevance: 0\n          },\n          {\n            className: 'string',\n            begin: '\\\\[',\n            end: '\\\\]',\n            excludeBegin: true,\n            excludeEnd: true,\n            relevance: 0\n          }\n        ],\n        relevance: 10\n      }\n    ]\n  };\n}\n\nmodule.exports = asciidoc;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: Bash\nAuthor: vah \nContributrors: Benjamin Pannell \nWebsite: https://www.gnu.org/software/bash/\nCategory: common\n*/\n\n/** @type LanguageFn */\nfunction bash(hljs) {\n  const VAR = {};\n  const BRACED_VAR = {\n    begin: /\\$\\{/,\n    end:/\\}/,\n    contains: [\n      \"self\",\n      {\n        begin: /:-/,\n        contains: [ VAR ]\n      } // default values\n    ]\n  };\n  Object.assign(VAR,{\n    className: 'variable',\n    variants: [\n      {begin: concat(/\\$[\\w\\d#@][\\w\\d_]*/,\n        // negative look-ahead tries to avoid matching patterns that are not\n        // Perl at all like $ident$, @ident@, etc.\n        `(?![\\\\w\\\\d])(?![$])`) },\n      BRACED_VAR\n    ]\n  });\n\n  const SUBST = {\n    className: 'subst',\n    begin: /\\$\\(/, end: /\\)/,\n    contains: [hljs.BACKSLASH_ESCAPE]\n  };\n  const HERE_DOC = {\n    begin: /<<-?\\s*(?=\\w+)/,\n    starts: {\n      contains: [\n        hljs.END_SAME_AS_BEGIN({\n          begin: /(\\w+)/,\n          end: /(\\w+)/,\n          className: 'string'\n        })\n      ]\n    }\n  };\n  const QUOTE_STRING = {\n    className: 'string',\n    begin: /\"/, end: /\"/,\n    contains: [\n      hljs.BACKSLASH_ESCAPE,\n      VAR,\n      SUBST\n    ]\n  };\n  SUBST.contains.push(QUOTE_STRING);\n  const ESCAPED_QUOTE = {\n    className: '',\n    begin: /\\\\\"/\n\n  };\n  const APOS_STRING = {\n    className: 'string',\n    begin: /'/, end: /'/\n  };\n  const ARITHMETIC = {\n    begin: /\\$\\(\\(/,\n    end: /\\)\\)/,\n    contains: [\n      { begin: /\\d+#[0-9a-f]+/, className: \"number\" },\n      hljs.NUMBER_MODE,\n      VAR\n    ]\n  };\n  const SH_LIKE_SHELLS = [\n    \"fish\",\n    \"bash\",\n    \"zsh\",\n    \"sh\",\n    \"csh\",\n    \"ksh\",\n    \"tcsh\",\n    \"dash\",\n    \"scsh\",\n  ];\n  const KNOWN_SHEBANG = hljs.SHEBANG({\n    binary: `(${SH_LIKE_SHELLS.join(\"|\")})`,\n    relevance: 10\n  });\n  const FUNCTION = {\n    className: 'function',\n    begin: /\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,\n    returnBegin: true,\n    contains: [hljs.inherit(hljs.TITLE_MODE, {begin: /\\w[\\w\\d_]*/})],\n    relevance: 0\n  };\n\n  return {\n    name: 'Bash',\n    aliases: ['sh', 'zsh'],\n    keywords: {\n      $pattern: /\\b[a-z._-]+\\b/,\n      keyword:\n        'if then else elif fi for while in do done case esac function',\n      literal:\n        'true false',\n      built_in:\n        // Shell built-ins\n        // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html\n        'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' +\n        'trap umask unset ' +\n        // Bash built-ins\n        'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' +\n        'read readarray source type typeset ulimit unalias ' +\n        // Shell modifiers\n        'set shopt ' +\n        // Zsh built-ins\n        'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' +\n        'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' +\n        'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' +\n        'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' +\n        'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' +\n        'zpty zregexparse zsocket zstyle ztcp'\n    },\n    contains: [\n      KNOWN_SHEBANG, // to catch known shells and boost relevancy\n      hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang\n      FUNCTION,\n      ARITHMETIC,\n      hljs.HASH_COMMENT_MODE,\n      HERE_DOC,\n      QUOTE_STRING,\n      ESCAPED_QUOTE,\n      APOS_STRING,\n      VAR\n    ]\n  };\n}\n\nmodule.exports = bash;\n","const MODES = (hljs) => {\n  return {\n    IMPORTANT: {\n      className: 'meta',\n      begin: '!important'\n    },\n    HEXCOLOR: {\n      className: 'number',\n      begin: '#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})'\n    },\n    ATTRIBUTE_SELECTOR_MODE: {\n      className: 'selector-attr',\n      begin: /\\[/,\n      end: /\\]/,\n      illegal: '$',\n      contains: [\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE\n      ]\n    }\n  };\n};\n\nconst TAGS = [\n  'a',\n  'abbr',\n  'address',\n  'article',\n  'aside',\n  'audio',\n  'b',\n  'blockquote',\n  'body',\n  'button',\n  'canvas',\n  'caption',\n  'cite',\n  'code',\n  'dd',\n  'del',\n  'details',\n  'dfn',\n  'div',\n  'dl',\n  'dt',\n  'em',\n  'fieldset',\n  'figcaption',\n  'figure',\n  'footer',\n  'form',\n  'h1',\n  'h2',\n  'h3',\n  'h4',\n  'h5',\n  'h6',\n  'header',\n  'hgroup',\n  'html',\n  'i',\n  'iframe',\n  'img',\n  'input',\n  'ins',\n  'kbd',\n  'label',\n  'legend',\n  'li',\n  'main',\n  'mark',\n  'menu',\n  'nav',\n  'object',\n  'ol',\n  'p',\n  'q',\n  'quote',\n  'samp',\n  'section',\n  'span',\n  'strong',\n  'summary',\n  'sup',\n  'table',\n  'tbody',\n  'td',\n  'textarea',\n  'tfoot',\n  'th',\n  'thead',\n  'time',\n  'tr',\n  'ul',\n  'var',\n  'video'\n];\n\nconst MEDIA_FEATURES = [\n  'any-hover',\n  'any-pointer',\n  'aspect-ratio',\n  'color',\n  'color-gamut',\n  'color-index',\n  'device-aspect-ratio',\n  'device-height',\n  'device-width',\n  'display-mode',\n  'forced-colors',\n  'grid',\n  'height',\n  'hover',\n  'inverted-colors',\n  'monochrome',\n  'orientation',\n  'overflow-block',\n  'overflow-inline',\n  'pointer',\n  'prefers-color-scheme',\n  'prefers-contrast',\n  'prefers-reduced-motion',\n  'prefers-reduced-transparency',\n  'resolution',\n  'scan',\n  'scripting',\n  'update',\n  'width',\n  // TODO: find a better solution?\n  'min-width',\n  'max-width',\n  'min-height',\n  'max-height'\n];\n\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes\nconst PSEUDO_CLASSES = [\n  'active',\n  'any-link',\n  'blank',\n  'checked',\n  'current',\n  'default',\n  'defined',\n  'dir', // dir()\n  'disabled',\n  'drop',\n  'empty',\n  'enabled',\n  'first',\n  'first-child',\n  'first-of-type',\n  'fullscreen',\n  'future',\n  'focus',\n  'focus-visible',\n  'focus-within',\n  'has', // has()\n  'host', // host or host()\n  'host-context', // host-context()\n  'hover',\n  'indeterminate',\n  'in-range',\n  'invalid',\n  'is', // is()\n  'lang', // lang()\n  'last-child',\n  'last-of-type',\n  'left',\n  'link',\n  'local-link',\n  'not', // not()\n  'nth-child', // nth-child()\n  'nth-col', // nth-col()\n  'nth-last-child', // nth-last-child()\n  'nth-last-col', // nth-last-col()\n  'nth-last-of-type', //nth-last-of-type()\n  'nth-of-type', //nth-of-type()\n  'only-child',\n  'only-of-type',\n  'optional',\n  'out-of-range',\n  'past',\n  'placeholder-shown',\n  'read-only',\n  'read-write',\n  'required',\n  'right',\n  'root',\n  'scope',\n  'target',\n  'target-within',\n  'user-invalid',\n  'valid',\n  'visited',\n  'where' // where()\n];\n\n// https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements\nconst PSEUDO_ELEMENTS = [\n  'after',\n  'backdrop',\n  'before',\n  'cue',\n  'cue-region',\n  'first-letter',\n  'first-line',\n  'grammar-error',\n  'marker',\n  'part',\n  'placeholder',\n  'selection',\n  'slotted',\n  'spelling-error'\n];\n\nconst ATTRIBUTES = [\n  'align-content',\n  'align-items',\n  'align-self',\n  'animation',\n  'animation-delay',\n  'animation-direction',\n  'animation-duration',\n  'animation-fill-mode',\n  'animation-iteration-count',\n  'animation-name',\n  'animation-play-state',\n  'animation-timing-function',\n  'auto',\n  'backface-visibility',\n  'background',\n  'background-attachment',\n  'background-clip',\n  'background-color',\n  'background-image',\n  'background-origin',\n  'background-position',\n  'background-repeat',\n  'background-size',\n  'border',\n  'border-bottom',\n  'border-bottom-color',\n  'border-bottom-left-radius',\n  'border-bottom-right-radius',\n  'border-bottom-style',\n  'border-bottom-width',\n  'border-collapse',\n  'border-color',\n  'border-image',\n  'border-image-outset',\n  'border-image-repeat',\n  'border-image-slice',\n  'border-image-source',\n  'border-image-width',\n  'border-left',\n  'border-left-color',\n  'border-left-style',\n  'border-left-width',\n  'border-radius',\n  'border-right',\n  'border-right-color',\n  'border-right-style',\n  'border-right-width',\n  'border-spacing',\n  'border-style',\n  'border-top',\n  'border-top-color',\n  'border-top-left-radius',\n  'border-top-right-radius',\n  'border-top-style',\n  'border-top-width',\n  'border-width',\n  'bottom',\n  'box-decoration-break',\n  'box-shadow',\n  'box-sizing',\n  'break-after',\n  'break-before',\n  'break-inside',\n  'caption-side',\n  'clear',\n  'clip',\n  'clip-path',\n  'color',\n  'column-count',\n  'column-fill',\n  'column-gap',\n  'column-rule',\n  'column-rule-color',\n  'column-rule-style',\n  'column-rule-width',\n  'column-span',\n  'column-width',\n  'columns',\n  'content',\n  'counter-increment',\n  'counter-reset',\n  'cursor',\n  'direction',\n  'display',\n  'empty-cells',\n  'filter',\n  'flex',\n  'flex-basis',\n  'flex-direction',\n  'flex-flow',\n  'flex-grow',\n  'flex-shrink',\n  'flex-wrap',\n  'float',\n  'font',\n  'font-display',\n  'font-family',\n  'font-feature-settings',\n  'font-kerning',\n  'font-language-override',\n  'font-size',\n  'font-size-adjust',\n  'font-smoothing',\n  'font-stretch',\n  'font-style',\n  'font-variant',\n  'font-variant-ligatures',\n  'font-variation-settings',\n  'font-weight',\n  'height',\n  'hyphens',\n  'icon',\n  'image-orientation',\n  'image-rendering',\n  'image-resolution',\n  'ime-mode',\n  'inherit',\n  'initial',\n  'justify-content',\n  'left',\n  'letter-spacing',\n  'line-height',\n  'list-style',\n  'list-style-image',\n  'list-style-position',\n  'list-style-type',\n  'margin',\n  'margin-bottom',\n  'margin-left',\n  'margin-right',\n  'margin-top',\n  'marks',\n  'mask',\n  'max-height',\n  'max-width',\n  'min-height',\n  'min-width',\n  'nav-down',\n  'nav-index',\n  'nav-left',\n  'nav-right',\n  'nav-up',\n  'none',\n  'normal',\n  'object-fit',\n  'object-position',\n  'opacity',\n  'order',\n  'orphans',\n  'outline',\n  'outline-color',\n  'outline-offset',\n  'outline-style',\n  'outline-width',\n  'overflow',\n  'overflow-wrap',\n  'overflow-x',\n  'overflow-y',\n  'padding',\n  'padding-bottom',\n  'padding-left',\n  'padding-right',\n  'padding-top',\n  'page-break-after',\n  'page-break-before',\n  'page-break-inside',\n  'perspective',\n  'perspective-origin',\n  'pointer-events',\n  'position',\n  'quotes',\n  'resize',\n  'right',\n  'src', // @font-face\n  'tab-size',\n  'table-layout',\n  'text-align',\n  'text-align-last',\n  'text-decoration',\n  'text-decoration-color',\n  'text-decoration-line',\n  'text-decoration-style',\n  'text-indent',\n  'text-overflow',\n  'text-rendering',\n  'text-shadow',\n  'text-transform',\n  'text-underline-position',\n  'top',\n  'transform',\n  'transform-origin',\n  'transform-style',\n  'transition',\n  'transition-delay',\n  'transition-duration',\n  'transition-property',\n  'transition-timing-function',\n  'unicode-bidi',\n  'vertical-align',\n  'visibility',\n  'white-space',\n  'widows',\n  'width',\n  'word-break',\n  'word-spacing',\n  'word-wrap',\n  'z-index'\n  // reverse makes sure longer attributes `font-weight` are matched fully\n  // instead of getting false positives on say `font`\n].reverse();\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: CSS\nCategory: common, css\nWebsite: https://developer.mozilla.org/en-US/docs/Web/CSS\n*/\n\n/** @type LanguageFn */\nfunction css(hljs) {\n  const modes = MODES(hljs);\n  const FUNCTION_DISPATCH = {\n    className: \"built_in\",\n    begin: /[\\w-]+(?=\\()/\n  };\n  const VENDOR_PREFIX = {\n    begin: /-(webkit|moz|ms|o)-(?=[a-z])/\n  };\n  const AT_MODIFIERS = \"and or not only\";\n  const AT_PROPERTY_RE = /@-?\\w[\\w]*(-\\w+)*/; // @-webkit-keyframes\n  const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';\n  const STRINGS = [\n    hljs.APOS_STRING_MODE,\n    hljs.QUOTE_STRING_MODE\n  ];\n\n  return {\n    name: 'CSS',\n    case_insensitive: true,\n    illegal: /[=|'\\$]/,\n    keywords: {\n      keyframePosition: \"from to\"\n    },\n    classNameAliases: {\n      // for visual continuity with `tag {}` and because we\n      // don't have a great class for this?\n      keyframePosition: \"selector-tag\"\n    },\n    contains: [\n      hljs.C_BLOCK_COMMENT_MODE,\n      VENDOR_PREFIX,\n      // to recognize keyframe 40% etc which are outside the scope of our\n      // attribute value mode\n      hljs.CSS_NUMBER_MODE,\n      {\n        className: 'selector-id',\n        begin: /#[A-Za-z0-9_-]+/,\n        relevance: 0\n      },\n      {\n        className: 'selector-class',\n        begin: '\\\\.' + IDENT_RE,\n        relevance: 0\n      },\n      modes.ATTRIBUTE_SELECTOR_MODE,\n      {\n        className: 'selector-pseudo',\n        variants: [\n          {\n            begin: ':(' + PSEUDO_CLASSES.join('|') + ')'\n          },\n          {\n            begin: '::(' + PSEUDO_ELEMENTS.join('|') + ')'\n          }\n        ]\n      },\n      // we may actually need this (12/2020)\n      // { // pseudo-selector params\n      //   begin: /\\(/,\n      //   end: /\\)/,\n      //   contains: [ hljs.CSS_NUMBER_MODE ]\n      // },\n      {\n        className: 'attribute',\n        begin: '\\\\b(' + ATTRIBUTES.join('|') + ')\\\\b'\n      },\n      // attribute values\n      {\n        begin: ':',\n        end: '[;}]',\n        contains: [\n          modes.HEXCOLOR,\n          modes.IMPORTANT,\n          hljs.CSS_NUMBER_MODE,\n          ...STRINGS,\n          // needed to highlight these as strings and to avoid issues with\n          // illegal characters that might be inside urls that would tigger the\n          // languages illegal stack\n          {\n            begin: /(url|data-uri)\\(/,\n            end: /\\)/,\n            relevance: 0, // from keywords\n            keywords: {\n              built_in: \"url data-uri\"\n            },\n            contains: [\n              {\n                className: \"string\",\n                // any character other than `)` as in `url()` will be the start\n                // of a string, which ends with `)` (from the parent mode)\n                begin: /[^)]/,\n                endsWithParent: true,\n                excludeEnd: true\n              }\n            ]\n          },\n          FUNCTION_DISPATCH\n        ]\n      },\n      {\n        begin: lookahead(/@/),\n        end: '[{;]',\n        relevance: 0,\n        illegal: /:/, // break on Less variables @var: ...\n        contains: [\n          {\n            className: 'keyword',\n            begin: AT_PROPERTY_RE\n          },\n          {\n            begin: /\\s/,\n            endsWithParent: true,\n            excludeEnd: true,\n            relevance: 0,\n            keywords: {\n              $pattern: /[a-z-]+/,\n              keyword: AT_MODIFIERS,\n              attribute: MEDIA_FEATURES.join(\" \")\n            },\n            contains: [\n              {\n                begin: /[a-z-]+(?=:)/,\n                className: \"attribute\"\n              },\n              ...STRINGS,\n              hljs.CSS_NUMBER_MODE\n            ]\n          }\n        ]\n      },\n      {\n        className: 'selector-tag',\n        begin: '\\\\b(' + TAGS.join('|') + ')\\\\b'\n      }\n    ]\n  };\n}\n\nmodule.exports = css;\n","/*\nLanguage: Diff\nDescription: Unified and context diff\nAuthor: Vasily Polovnyov \nWebsite: https://www.gnu.org/software/diffutils/\nCategory: common\n*/\n\n/** @type LanguageFn */\nfunction diff(hljs) {\n  return {\n    name: 'Diff',\n    aliases: ['patch'],\n    contains: [\n      {\n        className: 'meta',\n        relevance: 10,\n        variants: [\n          {\n            begin: /^@@ +-\\d+,\\d+ +\\+\\d+,\\d+ +@@/\n          },\n          {\n            begin: /^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$/\n          },\n          {\n            begin: /^--- +\\d+,\\d+ +----$/\n          }\n        ]\n      },\n      {\n        className: 'comment',\n        variants: [\n          {\n            begin: /Index: /,\n            end: /$/\n          },\n          {\n            begin: /^index/,\n            end: /$/\n          },\n          {\n            begin: /={3,}/,\n            end: /$/\n          },\n          {\n            begin: /^-{3}/,\n            end: /$/\n          },\n          {\n            begin: /^\\*{3} /,\n            end: /$/\n          },\n          {\n            begin: /^\\+{3}/,\n            end: /$/\n          },\n          {\n            begin: /^\\*{15}$/\n          },\n          {\n            begin: /^diff --git/,\n            end: /$/\n          }\n        ]\n      },\n      {\n        className: 'addition',\n        begin: /^\\+/,\n        end: /$/\n      },\n      {\n        className: 'deletion',\n        begin: /^-/,\n        end: /$/\n      },\n      {\n        className: 'addition',\n        begin: /^!/,\n        end: /$/\n      }\n    ]\n  };\n}\n\nmodule.exports = diff;\n","/*\nLanguage: Dockerfile\nRequires: bash.js\nAuthor: Alexis Hénaut \nDescription: language definition for Dockerfile files\nWebsite: https://docs.docker.com/engine/reference/builder/\nCategory: config\n*/\n\n/** @type LanguageFn */\nfunction dockerfile(hljs) {\n  return {\n    name: 'Dockerfile',\n    aliases: ['docker'],\n    case_insensitive: true,\n    keywords: 'from maintainer expose env arg user onbuild stopsignal',\n    contains: [\n      hljs.HASH_COMMENT_MODE,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      hljs.NUMBER_MODE,\n      {\n        beginKeywords: 'run cmd entrypoint volume add copy workdir label healthcheck shell',\n        starts: {\n          end: /[^\\\\]$/,\n          subLanguage: 'bash'\n        }\n      }\n    ],\n    illegal: '\nContributors: Anton Kochkov \nWebsite: https://en.wikipedia.org/wiki/Batch_file\n*/\n\n/** @type LanguageFn */\nfunction dos(hljs) {\n  const COMMENT = hljs.COMMENT(\n    /^\\s*@?rem\\b/, /$/,\n    {\n      relevance: 10\n    }\n  );\n  const LABEL = {\n    className: 'symbol',\n    begin: '^\\\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\\\s+label)',\n    relevance: 0\n  };\n  return {\n    name: 'Batch file (DOS)',\n    aliases: [\n      'bat',\n      'cmd'\n    ],\n    case_insensitive: true,\n    illegal: /\\/\\*/,\n    keywords: {\n      keyword:\n        'if else goto for in do call exit not exist errorlevel defined ' +\n        'equ neq lss leq gtr geq',\n      built_in:\n        'prn nul lpt3 lpt2 lpt1 con com4 com3 com2 com1 aux ' +\n        'shift cd dir echo setlocal endlocal set pause copy ' +\n        'append assoc at attrib break cacls cd chcp chdir chkdsk chkntfs cls cmd color ' +\n        'comp compact convert date dir diskcomp diskcopy doskey erase fs ' +\n        'find findstr format ftype graftabl help keyb label md mkdir mode more move path ' +\n        'pause print popd pushd promt rd recover rem rename replace restore rmdir shift ' +\n        'sort start subst time title tree type ver verify vol ' +\n        // winutils\n        'ping net ipconfig taskkill xcopy ren del'\n    },\n    contains: [\n      {\n        className: 'variable',\n        begin: /%%[^ ]|%[^ ]+?%|![^ ]+?!/\n      },\n      {\n        className: 'function',\n        begin: LABEL.begin,\n        end: 'goto:eof',\n        contains: [\n          hljs.inherit(hljs.TITLE_MODE, {\n            begin: '([_a-zA-Z]\\\\w*\\\\.)*([_a-zA-Z]\\\\w*:)?[_a-zA-Z]\\\\w*'\n          }),\n          COMMENT\n        ]\n      },\n      {\n        className: 'number',\n        begin: '\\\\b\\\\d+',\n        relevance: 0\n      },\n      COMMENT\n    ]\n  };\n}\n\nmodule.exports = dos;\n","/*\nLanguage: Gradle\nDescription: Gradle is an open-source build automation tool focused on flexibility and performance.\nWebsite: https://gradle.org\nAuthor: Damian Mee \n*/\n\nfunction gradle(hljs) {\n  return {\n    name: 'Gradle',\n    case_insensitive: true,\n    keywords: {\n      keyword:\n        'task project allprojects subprojects artifacts buildscript configurations ' +\n        'dependencies repositories sourceSets description delete from into include ' +\n        'exclude source classpath destinationDir includes options sourceCompatibility ' +\n        'targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant ' +\n        'def abstract break case catch continue default do else extends final finally ' +\n        'for if implements instanceof native new private protected public return static ' +\n        'switch synchronized throw throws transient try volatile while strictfp package ' +\n        'import false null super this true antlrtask checkstyle codenarc copy boolean ' +\n        'byte char class double float int interface long short void compile runTime ' +\n        'file fileTree abs any append asList asWritable call collect compareTo count ' +\n        'div dump each eachByte eachFile eachLine every find findAll flatten getAt ' +\n        'getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods ' +\n        'isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter ' +\n        'newReader newWriter next plus pop power previous print println push putAt read ' +\n        'readBytes readLines reverse reverseEach round size sort splitEachLine step subMap ' +\n        'times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader ' +\n        'withStream withWriter withWriterAppend write writeLine'\n    },\n    contains: [\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      hljs.NUMBER_MODE,\n      hljs.REGEXP_MODE\n\n    ]\n  };\n}\n\nmodule.exports = gradle;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\n Language: Groovy\n Author: Guillaume Laforge \n Description: Groovy programming language implementation inspired from Vsevolod's Java mode\n Website: https://groovy-lang.org\n */\n\nfunction variants(variants, obj = {}) {\n  obj.variants = variants;\n  return obj;\n}\n\nfunction groovy(hljs) {\n  const IDENT_RE = '[A-Za-z0-9_$]+';\n  const COMMENT = variants([\n    hljs.C_LINE_COMMENT_MODE,\n    hljs.C_BLOCK_COMMENT_MODE,\n    hljs.COMMENT(\n      '/\\\\*\\\\*',\n      '\\\\*/',\n      {\n        relevance: 0,\n        contains: [\n          {\n            // eat up @'s in emails to prevent them to be recognized as doctags\n            begin: /\\w+@/,\n            relevance: 0\n          },\n          {\n            className: 'doctag',\n            begin: '@[A-Za-z]+'\n          }\n        ]\n      }\n    )\n  ]);\n  const REGEXP = {\n    className: 'regexp',\n    begin: /~?\\/[^\\/\\n]+\\//,\n    contains: [ hljs.BACKSLASH_ESCAPE ]\n  };\n  const NUMBER = variants([\n    hljs.BINARY_NUMBER_MODE,\n    hljs.C_NUMBER_MODE\n  ]);\n  const STRING = variants([\n    {\n      begin: /\"\"\"/,\n      end: /\"\"\"/\n    },\n    {\n      begin: /'''/,\n      end: /'''/\n    },\n    {\n      begin: \"\\\\$/\",\n      end: \"/\\\\$\",\n      relevance: 10\n    },\n    hljs.APOS_STRING_MODE,\n    hljs.QUOTE_STRING_MODE\n  ],\n  {\n    className: \"string\"\n  }\n  );\n\n  return {\n    name: 'Groovy',\n    keywords: {\n      built_in: 'this super',\n      literal: 'true false null',\n      keyword:\n            'byte short char int long boolean float double void ' +\n            // groovy specific keywords\n            'def as in assert trait ' +\n            // common keywords with Java\n            'abstract static volatile transient public private protected synchronized final ' +\n            'class interface enum if else for while switch case break default continue ' +\n            'throw throws try catch finally implements extends new import package return instanceof'\n    },\n    contains: [\n      hljs.SHEBANG({\n        binary: \"groovy\",\n        relevance: 10\n      }),\n      COMMENT,\n      STRING,\n      REGEXP,\n      NUMBER,\n      {\n        className: 'class',\n        beginKeywords: 'class interface trait enum',\n        end: /\\{/,\n        illegal: ':',\n        contains: [\n          {\n            beginKeywords: 'extends implements'\n          },\n          hljs.UNDERSCORE_TITLE_MODE\n        ]\n      },\n      {\n        className: 'meta',\n        begin: '@[A-Za-z]+',\n        relevance: 0\n      },\n      {\n        // highlight map keys and named parameters as attrs\n        className: 'attr',\n        begin: IDENT_RE + '[ \\t]*:',\n        relevance: 0\n      },\n      {\n        // catch middle element of the ternary operator\n        // to avoid highlight it as a label, named parameter, or map key\n        begin: /\\?/,\n        end: /:/,\n        relevance: 0,\n        contains: [\n          COMMENT,\n          STRING,\n          REGEXP,\n          NUMBER,\n          'self'\n        ]\n      },\n      {\n        // highlight labeled statements\n        className: 'symbol',\n        begin: '^[ \\t]*' + lookahead(IDENT_RE + ':'),\n        excludeBegin: true,\n        end: IDENT_RE + ':',\n        relevance: 0\n      }\n    ],\n    illegal: /#|<\\//\n  };\n}\n\nmodule.exports = groovy;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: HTTP\nDescription: HTTP request and response headers with automatic body highlighting\nAuthor: Ivan Sagalaev \nCategory: common, protocols\nWebsite: https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview\n*/\n\nfunction http(hljs) {\n  const VERSION = 'HTTP/(2|1\\\\.[01])';\n  const HEADER_NAME = /[A-Za-z][A-Za-z0-9-]*/;\n  const HEADER = {\n    className: 'attribute',\n    begin: concat('^', HEADER_NAME, '(?=\\\\:\\\\s)'),\n    starts: {\n      contains: [\n        {\n          className: \"punctuation\",\n          begin: /: /,\n          relevance: 0,\n          starts: {\n            end: '$',\n            relevance: 0\n          }\n        }\n      ]\n    }\n  };\n  const HEADERS_AND_BODY = [\n    HEADER,\n    {\n      begin: '\\\\n\\\\n',\n      starts: { subLanguage: [], endsWithParent: true }\n    }\n  ];\n\n  return {\n    name: 'HTTP',\n    aliases: ['https'],\n    illegal: /\\S/,\n    contains: [\n      // response\n      {\n        begin: '^(?=' + VERSION + \" \\\\d{3})\",\n        end: /$/,\n        contains: [\n          {\n            className: \"meta\",\n            begin: VERSION\n          },\n          {\n            className: 'number', begin: '\\\\b\\\\d{3}\\\\b'\n          }\n        ],\n        starts: {\n          end: /\\b\\B/,\n          illegal: /\\S/,\n          contains: HEADERS_AND_BODY\n        }\n      },\n      // request\n      {\n        begin: '(?=^[A-Z]+ (.*?) ' + VERSION + '$)',\n        end: /$/,\n        contains: [\n          {\n            className: 'string',\n            begin: ' ',\n            end: ' ',\n            excludeBegin: true,\n            excludeEnd: true\n          },\n          {\n            className: \"meta\",\n            begin: VERSION\n          },\n          {\n            className: 'keyword',\n            begin: '[A-Z]+'\n          }\n        ],\n        starts: {\n          end: /\\b\\B/,\n          illegal: /\\S/,\n          contains: HEADERS_AND_BODY\n        }\n      },\n      // to allow headers to work even without a preamble\n      hljs.inherit(HEADER, {\n        relevance: 0\n      })\n    ]\n  };\n}\n\nmodule.exports = http;\n","// https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10\nvar decimalDigits = '[0-9](_*[0-9])*';\nvar frac = `\\\\.(${decimalDigits})`;\nvar hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';\nvar NUMERIC = {\n  className: 'number',\n  variants: [\n    // DecimalFloatingPointLiteral\n    // including ExponentPart\n    { begin: `(\\\\b(${decimalDigits})((${frac})|\\\\.)?|(${frac}))` +\n      `[eE][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n    // excluding ExponentPart\n    { begin: `\\\\b(${decimalDigits})((${frac})[fFdD]?\\\\b|\\\\.([fFdD]\\\\b)?)` },\n    { begin: `(${frac})[fFdD]?\\\\b` },\n    { begin: `\\\\b(${decimalDigits})[fFdD]\\\\b` },\n\n    // HexadecimalFloatingPointLiteral\n    { begin: `\\\\b0[xX]((${hexDigits})\\\\.?|(${hexDigits})?\\\\.(${hexDigits}))` +\n      `[pP][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n\n    // DecimalIntegerLiteral\n    { begin: '\\\\b(0|[1-9](_*[0-9])*)[lL]?\\\\b' },\n\n    // HexIntegerLiteral\n    { begin: `\\\\b0[xX](${hexDigits})[lL]?\\\\b` },\n\n    // OctalIntegerLiteral\n    { begin: '\\\\b0(_*[0-7])*[lL]?\\\\b' },\n\n    // BinaryIntegerLiteral\n    { begin: '\\\\b0[bB][01](_*[01])*[lL]?\\\\b' },\n  ],\n  relevance: 0\n};\n\n/*\nLanguage: Java\nAuthor: Vsevolod Solovyov \nCategory: common, enterprise\nWebsite: https://www.java.com/\n*/\n\nfunction java(hljs) {\n  var JAVA_IDENT_RE = '[\\u00C0-\\u02B8a-zA-Z_$][\\u00C0-\\u02B8a-zA-Z_$0-9]*';\n  var GENERIC_IDENT_RE = JAVA_IDENT_RE + '(<' + JAVA_IDENT_RE + '(\\\\s*,\\\\s*' + JAVA_IDENT_RE + ')*>)?';\n  var KEYWORDS = 'false synchronized int abstract float private char boolean var static null if const ' +\n    'for true while long strictfp finally protected import native final void ' +\n    'enum else break transient catch instanceof byte super volatile case assert short ' +\n    'package default double public try this switch continue throws protected public private ' +\n    'module requires exports do';\n\n  var ANNOTATION = {\n    className: 'meta',\n    begin: '@' + JAVA_IDENT_RE,\n    contains: [\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [\"self\"] // allow nested () inside our annotation\n      },\n    ]\n  };\n  const NUMBER = NUMERIC;\n\n  return {\n    name: 'Java',\n    aliases: ['jsp'],\n    keywords: KEYWORDS,\n    illegal: /<\\/|#/,\n    contains: [\n      hljs.COMMENT(\n        '/\\\\*\\\\*',\n        '\\\\*/',\n        {\n          relevance: 0,\n          contains: [\n            {\n              // eat up @'s in emails to prevent them to be recognized as doctags\n              begin: /\\w+@/, relevance: 0\n            },\n            {\n              className: 'doctag',\n              begin: '@[A-Za-z]+'\n            }\n          ]\n        }\n      ),\n      // relevance boost\n      {\n        begin: /import java\\.[a-z]+\\./,\n        keywords: \"import\",\n        relevance: 2\n      },\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      {\n        className: 'class',\n        beginKeywords: 'class interface enum', end: /[{;=]/, excludeEnd: true,\n        // TODO: can this be removed somehow?\n        // an extra boost because Java is more popular than other languages with\n        // this same syntax feature (this is just to preserve our tests passing\n        // for now)\n        relevance: 1,\n        keywords: 'class interface enum',\n        illegal: /[:\"\\[\\]]/,\n        contains: [\n          { beginKeywords: 'extends implements' },\n          hljs.UNDERSCORE_TITLE_MODE\n        ]\n      },\n      {\n        // Expression keywords prevent 'keyword Name(...)' from being\n        // recognized as a function definition\n        beginKeywords: 'new throw return else',\n        relevance: 0\n      },\n      {\n        className: 'class',\n        begin: 'record\\\\s+' + hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n        returnBegin: true,\n        excludeEnd: true,\n        end: /[{;=]/,\n        keywords: KEYWORDS,\n        contains: [\n          { beginKeywords: \"record\" },\n          {\n            begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n            returnBegin: true,\n            relevance: 0,\n            contains: [hljs.UNDERSCORE_TITLE_MODE]\n          },\n          {\n            className: 'params',\n            begin: /\\(/, end: /\\)/,\n            keywords: KEYWORDS,\n            relevance: 0,\n            contains: [\n              hljs.C_BLOCK_COMMENT_MODE\n            ]\n          },\n          hljs.C_LINE_COMMENT_MODE,\n          hljs.C_BLOCK_COMMENT_MODE\n        ]\n      },\n      {\n        className: 'function',\n        begin: '(' + GENERIC_IDENT_RE + '\\\\s+)+' + hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(', returnBegin: true, end: /[{;=]/,\n        excludeEnd: true,\n        keywords: KEYWORDS,\n        contains: [\n          {\n            begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(', returnBegin: true,\n            relevance: 0,\n            contains: [hljs.UNDERSCORE_TITLE_MODE]\n          },\n          {\n            className: 'params',\n            begin: /\\(/, end: /\\)/,\n            keywords: KEYWORDS,\n            relevance: 0,\n            contains: [\n              ANNOTATION,\n              hljs.APOS_STRING_MODE,\n              hljs.QUOTE_STRING_MODE,\n              NUMBER,\n              hljs.C_BLOCK_COMMENT_MODE\n            ]\n          },\n          hljs.C_LINE_COMMENT_MODE,\n          hljs.C_BLOCK_COMMENT_MODE\n        ]\n      },\n      NUMBER,\n      ANNOTATION\n    ]\n  };\n}\n\nmodule.exports = java;\n","const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';\nconst KEYWORDS = [\n  \"as\", // for exports\n  \"in\",\n  \"of\",\n  \"if\",\n  \"for\",\n  \"while\",\n  \"finally\",\n  \"var\",\n  \"new\",\n  \"function\",\n  \"do\",\n  \"return\",\n  \"void\",\n  \"else\",\n  \"break\",\n  \"catch\",\n  \"instanceof\",\n  \"with\",\n  \"throw\",\n  \"case\",\n  \"default\",\n  \"try\",\n  \"switch\",\n  \"continue\",\n  \"typeof\",\n  \"delete\",\n  \"let\",\n  \"yield\",\n  \"const\",\n  \"class\",\n  // JS handles these with a special rule\n  // \"get\",\n  // \"set\",\n  \"debugger\",\n  \"async\",\n  \"await\",\n  \"static\",\n  \"import\",\n  \"from\",\n  \"export\",\n  \"extends\"\n];\nconst LITERALS = [\n  \"true\",\n  \"false\",\n  \"null\",\n  \"undefined\",\n  \"NaN\",\n  \"Infinity\"\n];\n\nconst TYPES = [\n  \"Intl\",\n  \"DataView\",\n  \"Number\",\n  \"Math\",\n  \"Date\",\n  \"String\",\n  \"RegExp\",\n  \"Object\",\n  \"Function\",\n  \"Boolean\",\n  \"Error\",\n  \"Symbol\",\n  \"Set\",\n  \"Map\",\n  \"WeakSet\",\n  \"WeakMap\",\n  \"Proxy\",\n  \"Reflect\",\n  \"JSON\",\n  \"Promise\",\n  \"Float64Array\",\n  \"Int16Array\",\n  \"Int32Array\",\n  \"Int8Array\",\n  \"Uint16Array\",\n  \"Uint32Array\",\n  \"Float32Array\",\n  \"Array\",\n  \"Uint8Array\",\n  \"Uint8ClampedArray\",\n  \"ArrayBuffer\",\n  \"BigInt64Array\",\n  \"BigUint64Array\",\n  \"BigInt\"\n];\n\nconst ERROR_TYPES = [\n  \"EvalError\",\n  \"InternalError\",\n  \"RangeError\",\n  \"ReferenceError\",\n  \"SyntaxError\",\n  \"TypeError\",\n  \"URIError\"\n];\n\nconst BUILT_IN_GLOBALS = [\n  \"setInterval\",\n  \"setTimeout\",\n  \"clearInterval\",\n  \"clearTimeout\",\n\n  \"require\",\n  \"exports\",\n\n  \"eval\",\n  \"isFinite\",\n  \"isNaN\",\n  \"parseFloat\",\n  \"parseInt\",\n  \"decodeURI\",\n  \"decodeURIComponent\",\n  \"encodeURI\",\n  \"encodeURIComponent\",\n  \"escape\",\n  \"unescape\"\n];\n\nconst BUILT_IN_VARIABLES = [\n  \"arguments\",\n  \"this\",\n  \"super\",\n  \"console\",\n  \"window\",\n  \"document\",\n  \"localStorage\",\n  \"module\",\n  \"global\" // Node.js\n];\n\nconst BUILT_INS = [].concat(\n  BUILT_IN_GLOBALS,\n  BUILT_IN_VARIABLES,\n  TYPES,\n  ERROR_TYPES\n);\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: JavaScript\nDescription: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.\nCategory: common, scripting\nWebsite: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n*/\n\n/** @type LanguageFn */\nfunction javascript(hljs) {\n  /**\n   * Takes a string like \" {\n    const tag = \"',\n    end: ''\n  };\n  const XML_TAG = {\n    begin: /<[A-Za-z0-9\\\\._:-]+/,\n    end: /\\/[A-Za-z0-9\\\\._:-]+>|\\/>/,\n    /**\n     * @param {RegExpMatchArray} match\n     * @param {CallbackResponse} response\n     */\n    isTrulyOpeningTag: (match, response) => {\n      const afterMatchIndex = match[0].length + match.index;\n      const nextChar = match.input[afterMatchIndex];\n      // nested type?\n      // HTML should not include another raw `<` inside a tag\n      // But a type might: `>`, etc.\n      if (nextChar === \"<\") {\n        response.ignoreMatch();\n        return;\n      }\n      // \n      // This is now either a tag or a type.\n      if (nextChar === \">\") {\n        // if we cannot find a matching closing tag, then we\n        // will ignore it\n        if (!hasClosingTag(match, { after: afterMatchIndex })) {\n          response.ignoreMatch();\n        }\n      }\n    }\n  };\n  const KEYWORDS$1 = {\n    $pattern: IDENT_RE,\n    keyword: KEYWORDS,\n    literal: LITERALS,\n    built_in: BUILT_INS\n  };\n\n  // https://tc39.es/ecma262/#sec-literals-numeric-literals\n  const decimalDigits = '[0-9](_?[0-9])*';\n  const frac = `\\\\.(${decimalDigits})`;\n  // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral\n  // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals\n  const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;\n  const NUMBER = {\n    className: 'number',\n    variants: [\n      // DecimalLiteral\n      { begin: `(\\\\b(${decimalInteger})((${frac})|\\\\.)?|(${frac}))` +\n        `[eE][+-]?(${decimalDigits})\\\\b` },\n      { begin: `\\\\b(${decimalInteger})\\\\b((${frac})\\\\b|\\\\.)?|(${frac})\\\\b` },\n\n      // DecimalBigIntegerLiteral\n      { begin: `\\\\b(0|[1-9](_?[0-9])*)n\\\\b` },\n\n      // NonDecimalIntegerLiteral\n      { begin: \"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\\\b\" },\n      { begin: \"\\\\b0[bB][0-1](_?[0-1])*n?\\\\b\" },\n      { begin: \"\\\\b0[oO][0-7](_?[0-7])*n?\\\\b\" },\n\n      // LegacyOctalIntegerLiteral (does not include underscore separators)\n      // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals\n      { begin: \"\\\\b0[0-7]+n?\\\\b\" },\n    ],\n    relevance: 0\n  };\n\n  const SUBST = {\n    className: 'subst',\n    begin: '\\\\$\\\\{',\n    end: '\\\\}',\n    keywords: KEYWORDS$1,\n    contains: [] // defined later\n  };\n  const HTML_TEMPLATE = {\n    begin: 'html`',\n    end: '',\n    starts: {\n      end: '`',\n      returnEnd: false,\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        SUBST\n      ],\n      subLanguage: 'xml'\n    }\n  };\n  const CSS_TEMPLATE = {\n    begin: 'css`',\n    end: '',\n    starts: {\n      end: '`',\n      returnEnd: false,\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        SUBST\n      ],\n      subLanguage: 'css'\n    }\n  };\n  const TEMPLATE_STRING = {\n    className: 'string',\n    begin: '`',\n    end: '`',\n    contains: [\n      hljs.BACKSLASH_ESCAPE,\n      SUBST\n    ]\n  };\n  const JSDOC_COMMENT = hljs.COMMENT(\n    /\\/\\*\\*(?!\\/)/,\n    '\\\\*/',\n    {\n      relevance: 0,\n      contains: [\n        {\n          className: 'doctag',\n          begin: '@[A-Za-z]+',\n          contains: [\n            {\n              className: 'type',\n              begin: '\\\\{',\n              end: '\\\\}',\n              relevance: 0\n            },\n            {\n              className: 'variable',\n              begin: IDENT_RE$1 + '(?=\\\\s*(-)|$)',\n              endsParent: true,\n              relevance: 0\n            },\n            // eat spaces (not newlines) so we can find\n            // types or variables\n            {\n              begin: /(?=[^\\n])\\s/,\n              relevance: 0\n            }\n          ]\n        }\n      ]\n    }\n  );\n  const COMMENT = {\n    className: \"comment\",\n    variants: [\n      JSDOC_COMMENT,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.C_LINE_COMMENT_MODE\n    ]\n  };\n  const SUBST_INTERNALS = [\n    hljs.APOS_STRING_MODE,\n    hljs.QUOTE_STRING_MODE,\n    HTML_TEMPLATE,\n    CSS_TEMPLATE,\n    TEMPLATE_STRING,\n    NUMBER,\n    hljs.REGEXP_MODE\n  ];\n  SUBST.contains = SUBST_INTERNALS\n    .concat({\n      // we need to pair up {} inside our subst to prevent\n      // it from ending too early by matching another }\n      begin: /\\{/,\n      end: /\\}/,\n      keywords: KEYWORDS$1,\n      contains: [\n        \"self\"\n      ].concat(SUBST_INTERNALS)\n    });\n  const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);\n  const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([\n    // eat recursive parens in sub expressions\n    {\n      begin: /\\(/,\n      end: /\\)/,\n      keywords: KEYWORDS$1,\n      contains: [\"self\"].concat(SUBST_AND_COMMENTS)\n    }\n  ]);\n  const PARAMS = {\n    className: 'params',\n    begin: /\\(/,\n    end: /\\)/,\n    excludeBegin: true,\n    excludeEnd: true,\n    keywords: KEYWORDS$1,\n    contains: PARAMS_CONTAINS\n  };\n\n  return {\n    name: 'Javascript',\n    aliases: ['js', 'jsx', 'mjs', 'cjs'],\n    keywords: KEYWORDS$1,\n    // this will be extended by TypeScript\n    exports: { PARAMS_CONTAINS },\n    illegal: /#(?![$_A-z])/,\n    contains: [\n      hljs.SHEBANG({\n        label: \"shebang\",\n        binary: \"node\",\n        relevance: 5\n      }),\n      {\n        label: \"use_strict\",\n        className: 'meta',\n        relevance: 10,\n        begin: /^\\s*['\"]use (strict|asm)['\"]/\n      },\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      HTML_TEMPLATE,\n      CSS_TEMPLATE,\n      TEMPLATE_STRING,\n      COMMENT,\n      NUMBER,\n      { // object attr container\n        begin: concat(/[{,\\n]\\s*/,\n          // we need to look ahead to make sure that we actually have an\n          // attribute coming up so we don't steal a comma from a potential\n          // \"value\" container\n          //\n          // NOTE: this might not work how you think.  We don't actually always\n          // enter this mode and stay.  Instead it might merely match `,\n          // ` and then immediately end after the , because it\n          // fails to find any actual attrs. But this still does the job because\n          // it prevents the value contain rule from grabbing this instead and\n          // prevening this rule from firing when we actually DO have keys.\n          lookahead(concat(\n            // we also need to allow for multiple possible comments inbetween\n            // the first key:value pairing\n            /(((\\/\\/.*$)|(\\/\\*(\\*[^/]|[^*])*\\*\\/))\\s*)*/,\n            IDENT_RE$1 + '\\\\s*:'))),\n        relevance: 0,\n        contains: [\n          {\n            className: 'attr',\n            begin: IDENT_RE$1 + lookahead('\\\\s*:'),\n            relevance: 0\n          }\n        ]\n      },\n      { // \"value\" container\n        begin: '(' + hljs.RE_STARTERS_RE + '|\\\\b(case|return|throw)\\\\b)\\\\s*',\n        keywords: 'return throw case',\n        contains: [\n          COMMENT,\n          hljs.REGEXP_MODE,\n          {\n            className: 'function',\n            // we have to count the parens to make sure we actually have the\n            // correct bounding ( ) before the =>.  There could be any number of\n            // sub-expressions inside also surrounded by parens.\n            begin: '(\\\\(' +\n            '[^()]*(\\\\(' +\n            '[^()]*(\\\\(' +\n            '[^()]*' +\n            '\\\\)[^()]*)*' +\n            '\\\\)[^()]*)*' +\n            '\\\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\\\s*=>',\n            returnBegin: true,\n            end: '\\\\s*=>',\n            contains: [\n              {\n                className: 'params',\n                variants: [\n                  {\n                    begin: hljs.UNDERSCORE_IDENT_RE,\n                    relevance: 0\n                  },\n                  {\n                    className: null,\n                    begin: /\\(\\s*\\)/,\n                    skip: true\n                  },\n                  {\n                    begin: /\\(/,\n                    end: /\\)/,\n                    excludeBegin: true,\n                    excludeEnd: true,\n                    keywords: KEYWORDS$1,\n                    contains: PARAMS_CONTAINS\n                  }\n                ]\n              }\n            ]\n          },\n          { // could be a comma delimited list of params to a function call\n            begin: /,/, relevance: 0\n          },\n          {\n            className: '',\n            begin: /\\s/,\n            end: /\\s*/,\n            skip: true\n          },\n          { // JSX\n            variants: [\n              { begin: FRAGMENT.begin, end: FRAGMENT.end },\n              {\n                begin: XML_TAG.begin,\n                // we carefully check the opening tag to see if it truly\n                // is a tag and not a false positive\n                'on:begin': XML_TAG.isTrulyOpeningTag,\n                end: XML_TAG.end\n              }\n            ],\n            subLanguage: 'xml',\n            contains: [\n              {\n                begin: XML_TAG.begin,\n                end: XML_TAG.end,\n                skip: true,\n                contains: ['self']\n              }\n            ]\n          }\n        ],\n        relevance: 0\n      },\n      {\n        className: 'function',\n        beginKeywords: 'function',\n        end: /[{;]/,\n        excludeEnd: true,\n        keywords: KEYWORDS$1,\n        contains: [\n          'self',\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n          PARAMS\n        ],\n        illegal: /%/\n      },\n      {\n        // prevent this from getting swallowed up by function\n        // since they appear \"function like\"\n        beginKeywords: \"while if switch catch for\"\n      },\n      {\n        className: 'function',\n        // we have to count the parens to make sure we actually have the correct\n        // bounding ( ).  There could be any number of sub-expressions inside\n        // also surrounded by parens.\n        begin: hljs.UNDERSCORE_IDENT_RE +\n          '\\\\(' + // first parens\n          '[^()]*(\\\\(' +\n            '[^()]*(\\\\(' +\n              '[^()]*' +\n            '\\\\)[^()]*)*' +\n          '\\\\)[^()]*)*' +\n          '\\\\)\\\\s*\\\\{', // end parens\n        returnBegin:true,\n        contains: [\n          PARAMS,\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n        ]\n      },\n      // hack: prevents detection of keywords in some circumstances\n      // .keyword()\n      // $keyword = x\n      {\n        variants: [\n          { begin: '\\\\.' + IDENT_RE$1 },\n          { begin: '\\\\$' + IDENT_RE$1 }\n        ],\n        relevance: 0\n      },\n      { // ES6 class\n        className: 'class',\n        beginKeywords: 'class',\n        end: /[{;=]/,\n        excludeEnd: true,\n        illegal: /[:\"[\\]]/,\n        contains: [\n          { beginKeywords: 'extends' },\n          hljs.UNDERSCORE_TITLE_MODE\n        ]\n      },\n      {\n        begin: /\\b(?=constructor)/,\n        end: /[{;]/,\n        excludeEnd: true,\n        contains: [\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n          'self',\n          PARAMS\n        ]\n      },\n      {\n        begin: '(get|set)\\\\s+(?=' + IDENT_RE$1 + '\\\\()',\n        end: /\\{/,\n        keywords: \"get set\",\n        contains: [\n          hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),\n          { begin: /\\(\\)/ }, // eat to avoid empty params\n          PARAMS\n        ]\n      },\n      {\n        begin: /\\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`\n      }\n    ]\n  };\n}\n\nmodule.exports = javascript;\n","/*\nLanguage: JSON\nDescription: JSON (JavaScript Object Notation) is a lightweight data-interchange format.\nAuthor: Ivan Sagalaev \nWebsite: http://www.json.org\nCategory: common, protocols\n*/\n\nfunction json(hljs) {\n  const LITERALS = {\n    literal: 'true false null'\n  };\n  const ALLOWED_COMMENTS = [\n    hljs.C_LINE_COMMENT_MODE,\n    hljs.C_BLOCK_COMMENT_MODE\n  ];\n  const TYPES = [\n    hljs.QUOTE_STRING_MODE,\n    hljs.C_NUMBER_MODE\n  ];\n  const VALUE_CONTAINER = {\n    end: ',',\n    endsWithParent: true,\n    excludeEnd: true,\n    contains: TYPES,\n    keywords: LITERALS\n  };\n  const OBJECT = {\n    begin: /\\{/,\n    end: /\\}/,\n    contains: [\n      {\n        className: 'attr',\n        begin: /\"/,\n        end: /\"/,\n        contains: [hljs.BACKSLASH_ESCAPE],\n        illegal: '\\\\n'\n      },\n      hljs.inherit(VALUE_CONTAINER, {\n        begin: /:/\n      })\n    ].concat(ALLOWED_COMMENTS),\n    illegal: '\\\\S'\n  };\n  const ARRAY = {\n    begin: '\\\\[',\n    end: '\\\\]',\n    contains: [hljs.inherit(VALUE_CONTAINER)], // inherit is a workaround for a bug that makes shared modes with endsWithParent compile only the ending of one of the parents\n    illegal: '\\\\S'\n  };\n  TYPES.push(OBJECT, ARRAY);\n  ALLOWED_COMMENTS.forEach(function(rule) {\n    TYPES.push(rule);\n  });\n  return {\n    name: 'JSON',\n    contains: TYPES,\n    keywords: LITERALS,\n    illegal: '\\\\S'\n  };\n}\n\nmodule.exports = json;\n","// https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10\nvar decimalDigits = '[0-9](_*[0-9])*';\nvar frac = `\\\\.(${decimalDigits})`;\nvar hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';\nvar NUMERIC = {\n  className: 'number',\n  variants: [\n    // DecimalFloatingPointLiteral\n    // including ExponentPart\n    { begin: `(\\\\b(${decimalDigits})((${frac})|\\\\.)?|(${frac}))` +\n      `[eE][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n    // excluding ExponentPart\n    { begin: `\\\\b(${decimalDigits})((${frac})[fFdD]?\\\\b|\\\\.([fFdD]\\\\b)?)` },\n    { begin: `(${frac})[fFdD]?\\\\b` },\n    { begin: `\\\\b(${decimalDigits})[fFdD]\\\\b` },\n\n    // HexadecimalFloatingPointLiteral\n    { begin: `\\\\b0[xX]((${hexDigits})\\\\.?|(${hexDigits})?\\\\.(${hexDigits}))` +\n      `[pP][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n\n    // DecimalIntegerLiteral\n    { begin: '\\\\b(0|[1-9](_*[0-9])*)[lL]?\\\\b' },\n\n    // HexIntegerLiteral\n    { begin: `\\\\b0[xX](${hexDigits})[lL]?\\\\b` },\n\n    // OctalIntegerLiteral\n    { begin: '\\\\b0(_*[0-7])*[lL]?\\\\b' },\n\n    // BinaryIntegerLiteral\n    { begin: '\\\\b0[bB][01](_*[01])*[lL]?\\\\b' },\n  ],\n  relevance: 0\n};\n\n/*\n Language: Kotlin\n Description: Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native.\n Author: Sergey Mashkov \n Website: https://kotlinlang.org\n Category: common\n */\n\nfunction kotlin(hljs) {\n  const KEYWORDS = {\n    keyword:\n      'abstract as val var vararg get set class object open private protected public noinline ' +\n      'crossinline dynamic final enum if else do while for when throw try catch finally ' +\n      'import package is in fun override companion reified inline lateinit init ' +\n      'interface annotation data sealed internal infix operator out by constructor super ' +\n      'tailrec where const inner suspend typealias external expect actual',\n    built_in:\n      'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',\n    literal:\n      'true false null'\n  };\n  const KEYWORDS_WITH_LABEL = {\n    className: 'keyword',\n    begin: /\\b(break|continue|return|this)\\b/,\n    starts: {\n      contains: [\n        {\n          className: 'symbol',\n          begin: /@\\w+/\n        }\n      ]\n    }\n  };\n  const LABEL = {\n    className: 'symbol',\n    begin: hljs.UNDERSCORE_IDENT_RE + '@'\n  };\n\n  // for string templates\n  const SUBST = {\n    className: 'subst',\n    begin: /\\$\\{/,\n    end: /\\}/,\n    contains: [ hljs.C_NUMBER_MODE ]\n  };\n  const VARIABLE = {\n    className: 'variable',\n    begin: '\\\\$' + hljs.UNDERSCORE_IDENT_RE\n  };\n  const STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: '\"\"\"',\n        end: '\"\"\"(?=[^\"])',\n        contains: [\n          VARIABLE,\n          SUBST\n        ]\n      },\n      // Can't use built-in modes easily, as we want to use STRING in the meta\n      // context as 'meta-string' and there's no syntax to remove explicitly set\n      // classNames in built-in modes.\n      {\n        begin: '\\'',\n        end: '\\'',\n        illegal: /\\n/,\n        contains: [ hljs.BACKSLASH_ESCAPE ]\n      },\n      {\n        begin: '\"',\n        end: '\"',\n        illegal: /\\n/,\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          VARIABLE,\n          SUBST\n        ]\n      }\n    ]\n  };\n  SUBST.contains.push(STRING);\n\n  const ANNOTATION_USE_SITE = {\n    className: 'meta',\n    begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\\\s*:(?:\\\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'\n  };\n  const ANNOTATION = {\n    className: 'meta',\n    begin: '@' + hljs.UNDERSCORE_IDENT_RE,\n    contains: [\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [\n          hljs.inherit(STRING, {\n            className: 'meta-string'\n          })\n        ]\n      }\n    ]\n  };\n\n  // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals\n  // According to the doc above, the number mode of kotlin is the same as java 8,\n  // so the code below is copied from java.js\n  const KOTLIN_NUMBER_MODE = NUMERIC;\n  const KOTLIN_NESTED_COMMENT = hljs.COMMENT(\n    '/\\\\*', '\\\\*/',\n    {\n      contains: [ hljs.C_BLOCK_COMMENT_MODE ]\n    }\n  );\n  const KOTLIN_PAREN_TYPE = {\n    variants: [\n      {\n        className: 'type',\n        begin: hljs.UNDERSCORE_IDENT_RE\n      },\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [] // defined later\n      }\n    ]\n  };\n  const KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE;\n  KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ];\n  KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ];\n\n  return {\n    name: 'Kotlin',\n    aliases: [ 'kt', 'kts' ],\n    keywords: KEYWORDS,\n    contains: [\n      hljs.COMMENT(\n        '/\\\\*\\\\*',\n        '\\\\*/',\n        {\n          relevance: 0,\n          contains: [\n            {\n              className: 'doctag',\n              begin: '@[A-Za-z]+'\n            }\n          ]\n        }\n      ),\n      hljs.C_LINE_COMMENT_MODE,\n      KOTLIN_NESTED_COMMENT,\n      KEYWORDS_WITH_LABEL,\n      LABEL,\n      ANNOTATION_USE_SITE,\n      ANNOTATION,\n      {\n        className: 'function',\n        beginKeywords: 'fun',\n        end: '[(]|$',\n        returnBegin: true,\n        excludeEnd: true,\n        keywords: KEYWORDS,\n        relevance: 5,\n        contains: [\n          {\n            begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n            returnBegin: true,\n            relevance: 0,\n            contains: [ hljs.UNDERSCORE_TITLE_MODE ]\n          },\n          {\n            className: 'type',\n            begin: //,\n            keywords: 'reified',\n            relevance: 0\n          },\n          {\n            className: 'params',\n            begin: /\\(/,\n            end: /\\)/,\n            endsParent: true,\n            keywords: KEYWORDS,\n            relevance: 0,\n            contains: [\n              {\n                begin: /:/,\n                end: /[=,\\/]/,\n                endsWithParent: true,\n                contains: [\n                  KOTLIN_PAREN_TYPE,\n                  hljs.C_LINE_COMMENT_MODE,\n                  KOTLIN_NESTED_COMMENT\n                ],\n                relevance: 0\n              },\n              hljs.C_LINE_COMMENT_MODE,\n              KOTLIN_NESTED_COMMENT,\n              ANNOTATION_USE_SITE,\n              ANNOTATION,\n              STRING,\n              hljs.C_NUMBER_MODE\n            ]\n          },\n          KOTLIN_NESTED_COMMENT\n        ]\n      },\n      {\n        className: 'class',\n        beginKeywords: 'class interface trait', // remove 'trait' when removed from KEYWORDS\n        end: /[:\\{(]|$/,\n        excludeEnd: true,\n        illegal: 'extends implements',\n        contains: [\n          {\n            beginKeywords: 'public protected internal private constructor'\n          },\n          hljs.UNDERSCORE_TITLE_MODE,\n          {\n            className: 'type',\n            begin: //,\n            excludeBegin: true,\n            excludeEnd: true,\n            relevance: 0\n          },\n          {\n            className: 'type',\n            begin: /[,:]\\s*/,\n            end: /[<\\(,]|$/,\n            excludeBegin: true,\n            returnEnd: true\n          },\n          ANNOTATION_USE_SITE,\n          ANNOTATION\n        ]\n      },\n      STRING,\n      {\n        className: 'meta',\n        begin: \"^#!/usr/bin/env\",\n        end: '$',\n        illegal: '\\n'\n      },\n      KOTLIN_NUMBER_MODE\n    ]\n  };\n}\n\nmodule.exports = kotlin;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: Markdown\nRequires: xml.js\nAuthor: John Crepezzi \nWebsite: https://daringfireball.net/projects/markdown/\nCategory: common, markup\n*/\n\nfunction markdown(hljs) {\n  const INLINE_HTML = {\n    begin: /<\\/?[A-Za-z_]/,\n    end: '>',\n    subLanguage: 'xml',\n    relevance: 0\n  };\n  const HORIZONTAL_RULE = {\n    begin: '^[-\\\\*]{3,}',\n    end: '$'\n  };\n  const CODE = {\n    className: 'code',\n    variants: [\n      // TODO: fix to allow these to work with sublanguage also\n      {\n        begin: '(`{3,})[^`](.|\\\\n)*?\\\\1`*[ ]*'\n      },\n      {\n        begin: '(~{3,})[^~](.|\\\\n)*?\\\\1~*[ ]*'\n      },\n      // needed to allow markdown as a sublanguage to work\n      {\n        begin: '```',\n        end: '```+[ ]*$'\n      },\n      {\n        begin: '~~~',\n        end: '~~~+[ ]*$'\n      },\n      {\n        begin: '`.+?`'\n      },\n      {\n        begin: '(?=^( {4}|\\\\t))',\n        // use contains to gobble up multiple lines to allow the block to be whatever size\n        // but only have a single open/close tag vs one per line\n        contains: [\n          {\n            begin: '^( {4}|\\\\t)',\n            end: '(\\\\n)$'\n          }\n        ],\n        relevance: 0\n      }\n    ]\n  };\n  const LIST = {\n    className: 'bullet',\n    begin: '^[ \\t]*([*+-]|(\\\\d+\\\\.))(?=\\\\s+)',\n    end: '\\\\s+',\n    excludeEnd: true\n  };\n  const LINK_REFERENCE = {\n    begin: /^\\[[^\\n]+\\]:/,\n    returnBegin: true,\n    contains: [\n      {\n        className: 'symbol',\n        begin: /\\[/,\n        end: /\\]/,\n        excludeBegin: true,\n        excludeEnd: true\n      },\n      {\n        className: 'link',\n        begin: /:\\s*/,\n        end: /$/,\n        excludeBegin: true\n      }\n    ]\n  };\n  const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;\n  const LINK = {\n    variants: [\n      // too much like nested array access in so many languages\n      // to have any real relevance\n      {\n        begin: /\\[.+?\\]\\[.*?\\]/,\n        relevance: 0\n      },\n      // popular internet URLs\n      {\n        begin: /\\[.+?\\]\\(((data|javascript|mailto):|(?:http|ftp)s?:\\/\\/).*?\\)/,\n        relevance: 2\n      },\n      {\n        begin: concat(/\\[.+?\\]\\(/, URL_SCHEME, /:\\/\\/.*?\\)/),\n        relevance: 2\n      },\n      // relative urls\n      {\n        begin: /\\[.+?\\]\\([./?&#].*?\\)/,\n        relevance: 1\n      },\n      // whatever else, lower relevance (might not be a link at all)\n      {\n        begin: /\\[.+?\\]\\(.*?\\)/,\n        relevance: 0\n      }\n    ],\n    returnBegin: true,\n    contains: [\n      {\n        className: 'string',\n        relevance: 0,\n        begin: '\\\\[',\n        end: '\\\\]',\n        excludeBegin: true,\n        returnEnd: true\n      },\n      {\n        className: 'link',\n        relevance: 0,\n        begin: '\\\\]\\\\(',\n        end: '\\\\)',\n        excludeBegin: true,\n        excludeEnd: true\n      },\n      {\n        className: 'symbol',\n        relevance: 0,\n        begin: '\\\\]\\\\[',\n        end: '\\\\]',\n        excludeBegin: true,\n        excludeEnd: true\n      }\n    ]\n  };\n  const BOLD = {\n    className: 'strong',\n    contains: [], // defined later\n    variants: [\n      {\n        begin: /_{2}/,\n        end: /_{2}/\n      },\n      {\n        begin: /\\*{2}/,\n        end: /\\*{2}/\n      }\n    ]\n  };\n  const ITALIC = {\n    className: 'emphasis',\n    contains: [], // defined later\n    variants: [\n      {\n        begin: /\\*(?!\\*)/,\n        end: /\\*/\n      },\n      {\n        begin: /_(?!_)/,\n        end: /_/,\n        relevance: 0\n      }\n    ]\n  };\n  BOLD.contains.push(ITALIC);\n  ITALIC.contains.push(BOLD);\n\n  let CONTAINABLE = [\n    INLINE_HTML,\n    LINK\n  ];\n\n  BOLD.contains = BOLD.contains.concat(CONTAINABLE);\n  ITALIC.contains = ITALIC.contains.concat(CONTAINABLE);\n\n  CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);\n\n  const HEADER = {\n    className: 'section',\n    variants: [\n      {\n        begin: '^#{1,6}',\n        end: '$',\n        contains: CONTAINABLE\n      },\n      {\n        begin: '(?=^.+?\\\\n[=-]{2,}$)',\n        contains: [\n          {\n            begin: '^[=-]*$'\n          },\n          {\n            begin: '^',\n            end: \"\\\\n\",\n            contains: CONTAINABLE\n          }\n        ]\n      }\n    ]\n  };\n\n  const BLOCKQUOTE = {\n    className: 'quote',\n    begin: '^>\\\\s+',\n    contains: CONTAINABLE,\n    end: '$'\n  };\n\n  return {\n    name: 'Markdown',\n    aliases: [\n      'md',\n      'mkdown',\n      'mkd'\n    ],\n    contains: [\n      HEADER,\n      INLINE_HTML,\n      LIST,\n      BOLD,\n      ITALIC,\n      BLOCKQUOTE,\n      CODE,\n      HORIZONTAL_RULE,\n      LINK,\n      LINK_REFERENCE\n    ]\n  };\n}\n\nmodule.exports = markdown;\n","/*\nLanguage: Nix\nAuthor: Domen Kožar \nDescription: Nix functional language\nWebsite: http://nixos.org/nix\n*/\n\nfunction nix(hljs) {\n  const NIX_KEYWORDS = {\n    keyword:\n      'rec with let in inherit assert if else then',\n    literal:\n      'true false or and null',\n    built_in:\n      'import abort baseNameOf dirOf isNull builtins map removeAttrs throw ' +\n      'toString derivation'\n  };\n  const ANTIQUOTE = {\n    className: 'subst',\n    begin: /\\$\\{/,\n    end: /\\}/,\n    keywords: NIX_KEYWORDS\n  };\n  const ATTRS = {\n    begin: /[a-zA-Z0-9-_]+(\\s*=)/,\n    returnBegin: true,\n    relevance: 0,\n    contains: [\n      {\n        className: 'attr',\n        begin: /\\S+/\n      }\n    ]\n  };\n  const STRING = {\n    className: 'string',\n    contains: [ ANTIQUOTE ],\n    variants: [\n      {\n        begin: \"''\",\n        end: \"''\"\n      },\n      {\n        begin: '\"',\n        end: '\"'\n      }\n    ]\n  };\n  const EXPRESSIONS = [\n    hljs.NUMBER_MODE,\n    hljs.HASH_COMMENT_MODE,\n    hljs.C_BLOCK_COMMENT_MODE,\n    STRING,\n    ATTRS\n  ];\n  ANTIQUOTE.contains = EXPRESSIONS;\n  return {\n    name: 'Nix',\n    aliases: [ \"nixos\" ],\n    keywords: NIX_KEYWORDS,\n    contains: EXPRESSIONS\n  };\n}\n\nmodule.exports = nix;\n","/*\nLanguage: PowerShell\nDescription: PowerShell is a task-based command-line shell and scripting language built on .NET.\nAuthor: David Mohundro \nContributors: Nicholas Blumhardt , Victor Zhou , Nicolas Le Gall \nWebsite: https://docs.microsoft.com/en-us/powershell/\n*/\n\nfunction powershell(hljs) {\n  const TYPES = [\n    \"string\",\n    \"char\",\n    \"byte\",\n    \"int\",\n    \"long\",\n    \"bool\",\n    \"decimal\",\n    \"single\",\n    \"double\",\n    \"DateTime\",\n    \"xml\",\n    \"array\",\n    \"hashtable\",\n    \"void\"\n  ];\n\n  // https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands\n  const VALID_VERBS =\n    'Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|' +\n    'Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|' +\n    'Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|' +\n    'Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|' +\n    'ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|' +\n    'Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|' +\n    'Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|' +\n    'Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|' +\n    'Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|' +\n    'Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|' +\n    'Unprotect|Use|ForEach|Sort|Tee|Where';\n\n  const COMPARISON_OPERATORS =\n    '-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|' +\n    '-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|' +\n    '-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|' +\n    '-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|' +\n    '-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|' +\n    '-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|' +\n    '-split|-wildcard|-xor';\n\n  const KEYWORDS = {\n    $pattern: /-?[A-z\\.\\-]+\\b/,\n    keyword:\n      'if else foreach return do while until elseif begin for trap data dynamicparam ' +\n      'end break throw param continue finally in switch exit filter try process catch ' +\n      'hidden static parameter',\n    // \"echo\" relevance has been set to 0 to avoid auto-detect conflicts with shell transcripts\n    built_in:\n      'ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp ' +\n      'cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx ' +\n      'fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group ' +\n      'gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi ' +\n      'iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh ' +\n      'popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp ' +\n      'rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp ' +\n      'spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write'\n    // TODO: 'validate[A-Z]+' can't work in keywords\n  };\n\n  const TITLE_NAME_RE = /\\w[\\w\\d]*((-)[\\w\\d]+)*/;\n\n  const BACKTICK_ESCAPE = {\n    begin: '`[\\\\s\\\\S]',\n    relevance: 0\n  };\n\n  const VAR = {\n    className: 'variable',\n    variants: [\n      {\n        begin: /\\$\\B/\n      },\n      {\n        className: 'keyword',\n        begin: /\\$this/\n      },\n      {\n        begin: /\\$[\\w\\d][\\w\\d_:]*/\n      }\n    ]\n  };\n\n  const LITERAL = {\n    className: 'literal',\n    begin: /\\$(null|true|false)\\b/\n  };\n\n  const QUOTE_STRING = {\n    className: \"string\",\n    variants: [\n      {\n        begin: /\"/,\n        end: /\"/\n      },\n      {\n        begin: /@\"/,\n        end: /^\"@/\n      }\n    ],\n    contains: [\n      BACKTICK_ESCAPE,\n      VAR,\n      {\n        className: 'variable',\n        begin: /\\$[A-z]/,\n        end: /[^A-z]/\n      }\n    ]\n  };\n\n  const APOS_STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: /'/,\n        end: /'/\n      },\n      {\n        begin: /@'/,\n        end: /^'@/\n      }\n    ]\n  };\n\n  const PS_HELPTAGS = {\n    className: \"doctag\",\n    variants: [\n      /* no paramater help tags */\n      {\n        begin: /\\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/\n      },\n      /* one parameter help tags */\n      {\n        begin: /\\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\\s+\\S+/\n      }\n    ]\n  };\n\n  const PS_COMMENT = hljs.inherit(\n    hljs.COMMENT(null, null),\n    {\n      variants: [\n        /* single-line comment */\n        {\n          begin: /#/,\n          end: /$/\n        },\n        /* multi-line comment */\n        {\n          begin: /<#/,\n          end: /#>/\n        }\n      ],\n      contains: [ PS_HELPTAGS ]\n    }\n  );\n\n  const CMDLETS = {\n    className: 'built_in',\n    variants: [\n      {\n        begin: '('.concat(VALID_VERBS, ')+(-)[\\\\w\\\\d]+')\n      }\n    ]\n  };\n\n  const PS_CLASS = {\n    className: 'class',\n    beginKeywords: 'class enum',\n    end: /\\s*[{]/,\n    excludeEnd: true,\n    relevance: 0,\n    contains: [ hljs.TITLE_MODE ]\n  };\n\n  const PS_FUNCTION = {\n    className: 'function',\n    begin: /function\\s+/,\n    end: /\\s*\\{|$/,\n    excludeEnd: true,\n    returnBegin: true,\n    relevance: 0,\n    contains: [\n      {\n        begin: \"function\",\n        relevance: 0,\n        className: \"keyword\"\n      },\n      {\n        className: \"title\",\n        begin: TITLE_NAME_RE,\n        relevance: 0\n      },\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        className: \"params\",\n        relevance: 0,\n        contains: [ VAR ]\n      }\n      // CMDLETS\n    ]\n  };\n\n  // Using statment, plus type, plus assembly name.\n  const PS_USING = {\n    begin: /using\\s/,\n    end: /$/,\n    returnBegin: true,\n    contains: [\n      QUOTE_STRING,\n      APOS_STRING,\n      {\n        className: 'keyword',\n        begin: /(using|assembly|command|module|namespace|type)/\n      }\n    ]\n  };\n\n  // Comperison operators & function named parameters.\n  const PS_ARGUMENTS = {\n    variants: [\n      // PS literals are pretty verbose so it's a good idea to accent them a bit.\n      {\n        className: 'operator',\n        begin: '('.concat(COMPARISON_OPERATORS, ')\\\\b')\n      },\n      {\n        className: 'literal',\n        begin: /(-)[\\w\\d]+/,\n        relevance: 0\n      }\n    ]\n  };\n\n  const HASH_SIGNS = {\n    className: 'selector-tag',\n    begin: /@\\B/,\n    relevance: 0\n  };\n\n  // It's a very general rule so I'll narrow it a bit with some strict boundaries\n  // to avoid any possible false-positive collisions!\n  const PS_METHODS = {\n    className: 'function',\n    begin: /\\[.*\\]\\s*[\\w]+[ ]??\\(/,\n    end: /$/,\n    returnBegin: true,\n    relevance: 0,\n    contains: [\n      {\n        className: 'keyword',\n        begin: '('.concat(\n          KEYWORDS.keyword.toString().replace(/\\s/g, '|'\n          ), ')\\\\b'),\n        endsParent: true,\n        relevance: 0\n      },\n      hljs.inherit(hljs.TITLE_MODE, {\n        endsParent: true\n      })\n    ]\n  };\n\n  const GENTLEMANS_SET = [\n    // STATIC_MEMBER,\n    PS_METHODS,\n    PS_COMMENT,\n    BACKTICK_ESCAPE,\n    hljs.NUMBER_MODE,\n    QUOTE_STRING,\n    APOS_STRING,\n    // PS_NEW_OBJECT_TYPE,\n    CMDLETS,\n    VAR,\n    LITERAL,\n    HASH_SIGNS\n  ];\n\n  const PS_TYPE = {\n    begin: /\\[/,\n    end: /\\]/,\n    excludeBegin: true,\n    excludeEnd: true,\n    relevance: 0,\n    contains: [].concat(\n      'self',\n      GENTLEMANS_SET,\n      {\n        begin: \"(\" + TYPES.join(\"|\") + \")\",\n        className: \"built_in\",\n        relevance: 0\n      },\n      {\n        className: 'type',\n        begin: /[\\.\\w\\d]+/,\n        relevance: 0\n      }\n    )\n  };\n\n  PS_METHODS.contains.unshift(PS_TYPE);\n\n  return {\n    name: 'PowerShell',\n    aliases: [\n      \"ps\",\n      \"ps1\"\n    ],\n    case_insensitive: true,\n    keywords: KEYWORDS,\n    contains: GENTLEMANS_SET.concat(\n      PS_CLASS,\n      PS_FUNCTION,\n      PS_USING,\n      PS_ARGUMENTS,\n      PS_TYPE\n    )\n  };\n}\n\nmodule.exports = powershell;\n","/*\nLanguage: .properties\nContributors: Valentin Aitken , Egor Rogov \nWebsite: https://en.wikipedia.org/wiki/.properties\nCategory: common, config\n*/\n\nfunction properties(hljs) {\n\n  // whitespaces: space, tab, formfeed\n  var WS0 = '[ \\\\t\\\\f]*';\n  var WS1 = '[ \\\\t\\\\f]+';\n  // delimiter\n  var EQUAL_DELIM = WS0+'[:=]'+WS0;\n  var WS_DELIM = WS1;\n  var DELIM = '(' + EQUAL_DELIM + '|' + WS_DELIM + ')';\n  var KEY_ALPHANUM = '([^\\\\\\\\\\\\W:= \\\\t\\\\f\\\\n]|\\\\\\\\.)+';\n  var KEY_OTHER = '([^\\\\\\\\:= \\\\t\\\\f\\\\n]|\\\\\\\\.)+';\n\n  var DELIM_AND_VALUE = {\n          // skip DELIM\n          end: DELIM,\n          relevance: 0,\n          starts: {\n            // value: everything until end of line (again, taking into account backslashes)\n            className: 'string',\n            end: /$/,\n            relevance: 0,\n            contains: [\n              { begin: '\\\\\\\\\\\\\\\\'},\n              { begin: '\\\\\\\\\\\\n' }\n            ]\n          }\n        };\n\n  return {\n    name: '.properties',\n    case_insensitive: true,\n    illegal: /\\S/,\n    contains: [\n      hljs.COMMENT('^\\\\s*[!#]', '$'),\n      // key: everything until whitespace or = or : (taking into account backslashes)\n      // case of a \"normal\" key\n      {\n        returnBegin: true,\n        variants: [\n          { begin: KEY_ALPHANUM + EQUAL_DELIM, relevance: 1 },\n          { begin: KEY_ALPHANUM + WS_DELIM, relevance: 0 }\n        ],\n        contains: [\n          {\n            className: 'attr',\n            begin: KEY_ALPHANUM,\n            endsParent: true,\n            relevance: 0\n          }\n        ],\n        starts: DELIM_AND_VALUE\n      },\n      // case of key containing non-alphanumeric chars => relevance = 0\n      {\n        begin: KEY_OTHER + DELIM,\n        returnBegin: true,\n        relevance: 0,\n        contains: [\n          {\n            className: 'meta',\n            begin: KEY_OTHER,\n            endsParent: true,\n            relevance: 0\n          }\n        ],\n        starts: DELIM_AND_VALUE\n      },\n      // case of an empty key\n      {\n        className: 'attr',\n        relevance: 0,\n        begin: KEY_OTHER + WS0 + '$'\n      }\n    ]\n  };\n}\n\nmodule.exports = properties;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/*\nLanguage: Ruby\nDescription: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.\nWebsite: https://www.ruby-lang.org/\nAuthor: Anton Kovalyov \nContributors: Peter Leonov , Vasily Polovnyov , Loren Segal , Pascal Hurni , Cedric Sohrauer \nCategory: common\n*/\n\nfunction ruby(hljs) {\n  const RUBY_METHOD_RE = '([a-zA-Z_]\\\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?)';\n  const RUBY_KEYWORDS = {\n    keyword:\n      'and then defined module in return redo if BEGIN retry end for self when ' +\n      'next until do begin unless END rescue else break undef not super class case ' +\n      'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor ' +\n      '__FILE__',\n    built_in: 'proc lambda',\n    literal:\n      'true false nil'\n  };\n  const YARDOCTAG = {\n    className: 'doctag',\n    begin: '@[A-Za-z]+'\n  };\n  const IRB_OBJECT = {\n    begin: '#<',\n    end: '>'\n  };\n  const COMMENT_MODES = [\n    hljs.COMMENT(\n      '#',\n      '$',\n      {\n        contains: [ YARDOCTAG ]\n      }\n    ),\n    hljs.COMMENT(\n      '^=begin',\n      '^=end',\n      {\n        contains: [ YARDOCTAG ],\n        relevance: 10\n      }\n    ),\n    hljs.COMMENT('^__END__', '\\\\n$')\n  ];\n  const SUBST = {\n    className: 'subst',\n    begin: /#\\{/,\n    end: /\\}/,\n    keywords: RUBY_KEYWORDS\n  };\n  const STRING = {\n    className: 'string',\n    contains: [\n      hljs.BACKSLASH_ESCAPE,\n      SUBST\n    ],\n    variants: [\n      {\n        begin: /'/,\n        end: /'/\n      },\n      {\n        begin: /\"/,\n        end: /\"/\n      },\n      {\n        begin: /`/,\n        end: /`/\n      },\n      {\n        begin: /%[qQwWx]?\\(/,\n        end: /\\)/\n      },\n      {\n        begin: /%[qQwWx]?\\[/,\n        end: /\\]/\n      },\n      {\n        begin: /%[qQwWx]?\\{/,\n        end: /\\}/\n      },\n      {\n        begin: /%[qQwWx]?/\n      },\n      {\n        begin: /%[qQwWx]?\\//,\n        end: /\\//\n      },\n      {\n        begin: /%[qQwWx]?%/,\n        end: /%/\n      },\n      {\n        begin: /%[qQwWx]?-/,\n        end: /-/\n      },\n      {\n        begin: /%[qQwWx]?\\|/,\n        end: /\\|/\n      },\n      // in the following expressions, \\B in the beginning suppresses recognition of ?-sequences\n      // where ? is the last character of a preceding identifier, as in: `func?4`\n      {\n        begin: /\\B\\?(\\\\\\d{1,3})/\n      },\n      {\n        begin: /\\B\\?(\\\\x[A-Fa-f0-9]{1,2})/\n      },\n      {\n        begin: /\\B\\?(\\\\u\\{?[A-Fa-f0-9]{1,6}\\}?)/\n      },\n      {\n        begin: /\\B\\?(\\\\M-\\\\C-|\\\\M-\\\\c|\\\\c\\\\M-|\\\\M-|\\\\C-\\\\M-)[\\x20-\\x7e]/\n      },\n      {\n        begin: /\\B\\?\\\\(c|C-)[\\x20-\\x7e]/\n      },\n      {\n        begin: /\\B\\?\\\\?\\S/\n      },\n      { // heredocs\n        begin: /<<[-~]?'?(\\w+)\\n(?:[^\\n]*\\n)*?\\s*\\1\\b/,\n        returnBegin: true,\n        contains: [\n          {\n            begin: /<<[-~]?'?/\n          },\n          hljs.END_SAME_AS_BEGIN({\n            begin: /(\\w+)/,\n            end: /(\\w+)/,\n            contains: [\n              hljs.BACKSLASH_ESCAPE,\n              SUBST\n            ]\n          })\n        ]\n      }\n    ]\n  };\n\n  // Ruby syntax is underdocumented, but this grammar seems to be accurate\n  // as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)\n  // https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers\n  const decimal = '[1-9](_?[0-9])*|0';\n  const digits = '[0-9](_?[0-9])*';\n  const NUMBER = {\n    className: 'number',\n    relevance: 0,\n    variants: [\n      // decimal integer/float, optionally exponential or rational, optionally imaginary\n      {\n        begin: `\\\\b(${decimal})(\\\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\\\b`\n      },\n\n      // explicit decimal/binary/octal/hexadecimal integer,\n      // optionally rational and/or imaginary\n      {\n        begin: \"\\\\b0[dD][0-9](_?[0-9])*r?i?\\\\b\"\n      },\n      {\n        begin: \"\\\\b0[bB][0-1](_?[0-1])*r?i?\\\\b\"\n      },\n      {\n        begin: \"\\\\b0[oO][0-7](_?[0-7])*r?i?\\\\b\"\n      },\n      {\n        begin: \"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\\\b\"\n      },\n\n      // 0-prefixed implicit octal integer, optionally rational and/or imaginary\n      {\n        begin: \"\\\\b0(_?[0-7])+r?i?\\\\b\"\n      }\n    ]\n  };\n\n  const PARAMS = {\n    className: 'params',\n    begin: '\\\\(',\n    end: '\\\\)',\n    endsParent: true,\n    keywords: RUBY_KEYWORDS\n  };\n\n  const RUBY_DEFAULT_CONTAINS = [\n    STRING,\n    {\n      className: 'class',\n      beginKeywords: 'class module',\n      end: '$|;',\n      illegal: /=/,\n      contains: [\n        hljs.inherit(hljs.TITLE_MODE, {\n          begin: '[A-Za-z_]\\\\w*(::\\\\w+)*(\\\\?|!)?'\n        }),\n        {\n          begin: '<\\\\s*',\n          contains: [\n            {\n              begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE,\n              // we already get points for <, we don't need poitns\n              // for the name also\n              relevance: 0\n            }\n          ]\n        }\n      ].concat(COMMENT_MODES)\n    },\n    {\n      className: 'function',\n      // def method_name(\n      // def method_name;\n      // def method_name (end of line)\n      begin: concat(/def\\s+/, lookahead(RUBY_METHOD_RE + \"\\\\s*(\\\\(|;|$)\")),\n      relevance: 0, // relevance comes from kewords\n      keywords: \"def\",\n      end: '$|;',\n      contains: [\n        hljs.inherit(hljs.TITLE_MODE, {\n          begin: RUBY_METHOD_RE\n        }),\n        PARAMS\n      ].concat(COMMENT_MODES)\n    },\n    {\n      // swallow namespace qualifiers before symbols\n      begin: hljs.IDENT_RE + '::'\n    },\n    {\n      className: 'symbol',\n      begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\\\?)?:',\n      relevance: 0\n    },\n    {\n      className: 'symbol',\n      begin: ':(?!\\\\s)',\n      contains: [\n        STRING,\n        {\n          begin: RUBY_METHOD_RE\n        }\n      ],\n      relevance: 0\n    },\n    NUMBER,\n    {\n      // negative-look forward attemps to prevent false matches like:\n      // @ident@ or $ident$ that might indicate this is not ruby at all\n      className: \"variable\",\n      begin: '(\\\\$\\\\W)|((\\\\$|@@?)(\\\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`\n    },\n    {\n      className: 'params',\n      begin: /\\|/,\n      end: /\\|/,\n      relevance: 0, // this could be a lot of things (in other languages) other than params\n      keywords: RUBY_KEYWORDS\n    },\n    { // regexp container\n      begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\\\s*',\n      keywords: 'unless',\n      contains: [\n        {\n          className: 'regexp',\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            SUBST\n          ],\n          illegal: /\\n/,\n          variants: [\n            {\n              begin: '/',\n              end: '/[a-z]*'\n            },\n            {\n              begin: /%r\\{/,\n              end: /\\}[a-z]*/\n            },\n            {\n              begin: '%r\\\\(',\n              end: '\\\\)[a-z]*'\n            },\n            {\n              begin: '%r!',\n              end: '![a-z]*'\n            },\n            {\n              begin: '%r\\\\[',\n              end: '\\\\][a-z]*'\n            }\n          ]\n        }\n      ].concat(IRB_OBJECT, COMMENT_MODES),\n      relevance: 0\n    }\n  ].concat(IRB_OBJECT, COMMENT_MODES);\n\n  SUBST.contains = RUBY_DEFAULT_CONTAINS;\n  PARAMS.contains = RUBY_DEFAULT_CONTAINS;\n\n  // >>\n  // ?>\n  const SIMPLE_PROMPT = \"[>?]>\";\n  // irb(main):001:0>\n  const DEFAULT_PROMPT = \"[\\\\w#]+\\\\(\\\\w+\\\\):\\\\d+:\\\\d+>\";\n  const RVM_PROMPT = \"(\\\\w+-)?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(p\\\\d+)?[^\\\\d][^>]+>\";\n\n  const IRB_DEFAULT = [\n    {\n      begin: /^\\s*=>/,\n      starts: {\n        end: '$',\n        contains: RUBY_DEFAULT_CONTAINS\n      }\n    },\n    {\n      className: 'meta',\n      begin: '^(' + SIMPLE_PROMPT + \"|\" + DEFAULT_PROMPT + '|' + RVM_PROMPT + ')(?=[ ])',\n      starts: {\n        end: '$',\n        contains: RUBY_DEFAULT_CONTAINS\n      }\n    }\n  ];\n\n  COMMENT_MODES.unshift(IRB_OBJECT);\n\n  return {\n    name: 'Ruby',\n    aliases: [\n      'rb',\n      'gemspec',\n      'podspec',\n      'thor',\n      'irb'\n    ],\n    keywords: RUBY_KEYWORDS,\n    illegal: /\\/\\*/,\n    contains: [\n      hljs.SHEBANG({\n        binary: \"ruby\"\n      })\n    ]\n      .concat(IRB_DEFAULT)\n      .concat(COMMENT_MODES)\n      .concat(RUBY_DEFAULT_CONTAINS)\n  };\n}\n\nmodule.exports = ruby;\n","/*\nLanguage: Scala\nCategory: functional\nAuthor: Jan Berkel \nContributors: Erik Osheim \nWebsite: https://www.scala-lang.org\n*/\n\nfunction scala(hljs) {\n  const ANNOTATION = {\n    className: 'meta',\n    begin: '@[A-Za-z]+'\n  };\n\n  // used in strings for escaping/interpolation/substitution\n  const SUBST = {\n    className: 'subst',\n    variants: [\n      {\n        begin: '\\\\$[A-Za-z0-9_]+'\n      },\n      {\n        begin: /\\$\\{/,\n        end: /\\}/\n      }\n    ]\n  };\n\n  const STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: '\"\"\"',\n        end: '\"\"\"'\n      },\n      {\n        begin: '\"',\n        end: '\"',\n        illegal: '\\\\n',\n        contains: [ hljs.BACKSLASH_ESCAPE ]\n      },\n      {\n        begin: '[a-z]+\"',\n        end: '\"',\n        illegal: '\\\\n',\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          SUBST\n        ]\n      },\n      {\n        className: 'string',\n        begin: '[a-z]+\"\"\"',\n        end: '\"\"\"',\n        contains: [ SUBST ],\n        relevance: 10\n      }\n    ]\n\n  };\n\n  const SYMBOL = {\n    className: 'symbol',\n    begin: '\\'\\\\w[\\\\w\\\\d_]*(?!\\')'\n  };\n\n  const TYPE = {\n    className: 'type',\n    begin: '\\\\b[A-Z][A-Za-z0-9_]*',\n    relevance: 0\n  };\n\n  const NAME = {\n    className: 'title',\n    begin: /[^0-9\\n\\t \"'(),.`{}\\[\\]:;][^\\n\\t \"'(),.`{}\\[\\]:;]+|[^0-9\\n\\t \"'(),.`{}\\[\\]:;=]/,\n    relevance: 0\n  };\n\n  const CLASS = {\n    className: 'class',\n    beginKeywords: 'class object trait type',\n    end: /[:={\\[\\n;]/,\n    excludeEnd: true,\n    contains: [\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      {\n        beginKeywords: 'extends with',\n        relevance: 10\n      },\n      {\n        begin: /\\[/,\n        end: /\\]/,\n        excludeBegin: true,\n        excludeEnd: true,\n        relevance: 0,\n        contains: [ TYPE ]\n      },\n      {\n        className: 'params',\n        begin: /\\(/,\n        end: /\\)/,\n        excludeBegin: true,\n        excludeEnd: true,\n        relevance: 0,\n        contains: [ TYPE ]\n      },\n      NAME\n    ]\n  };\n\n  const METHOD = {\n    className: 'function',\n    beginKeywords: 'def',\n    end: /[:={\\[(\\n;]/,\n    excludeEnd: true,\n    contains: [ NAME ]\n  };\n\n  return {\n    name: 'Scala',\n    keywords: {\n      literal: 'true false null',\n      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'\n    },\n    contains: [\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      STRING,\n      SYMBOL,\n      TYPE,\n      METHOD,\n      CLASS,\n      hljs.C_NUMBER_MODE,\n      ANNOTATION\n    ]\n  };\n}\n\nmodule.exports = scala;\n","/*\nLanguage: Shell Session\nRequires: bash.js\nAuthor: TSUYUSATO Kitsune \nCategory: common\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction shell(hljs) {\n  return {\n    name: 'Shell Session',\n    aliases: [ 'console' ],\n    contains: [\n      {\n        className: 'meta',\n        // We cannot add \\s (spaces) in the regular expression otherwise it will be too broad and produce unexpected result.\n        // For instance, in the following example, it would match \"echo /path/to/home >\" as a prompt:\n        // echo /path/to/home > t.exe\n        begin: /^\\s{0,3}[/~\\w\\d[\\]()@-]*[>%$#]/,\n        starts: {\n          end: /[^\\\\](?=\\s*$)/,\n          subLanguage: 'bash'\n        }\n      }\n    ]\n  };\n}\n\nmodule.exports = shell;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] } args\n * @returns {string}\n */\nfunction either(...args) {\n  const joined = '(' + args.map((x) => source(x)).join(\"|\") + \")\";\n  return joined;\n}\n\n/*\n Language: SQL\n Website: https://en.wikipedia.org/wiki/SQL\n Category: common, database\n */\n\nfunction sql(hljs) {\n  const COMMENT_MODE = hljs.COMMENT('--', '$');\n  const STRING = {\n    className: 'string',\n    variants: [\n      {\n        begin: /'/,\n        end: /'/,\n        contains: [\n          {begin: /''/ }\n        ]\n      }\n    ]\n  };\n  const QUOTED_IDENTIFIER = {\n    begin: /\"/,\n    end: /\"/,\n    contains: [ { begin: /\"\"/ } ]\n  };\n\n  const LITERALS = [\n    \"true\",\n    \"false\",\n    // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.\n    // \"null\",\n    \"unknown\"\n  ];\n\n  const MULTI_WORD_TYPES = [\n    \"double precision\",\n    \"large object\",\n    \"with timezone\",\n    \"without timezone\"\n  ];\n\n  const TYPES = [\n    'bigint',\n    'binary',\n    'blob',\n    'boolean',\n    'char',\n    'character',\n    'clob',\n    'date',\n    'dec',\n    'decfloat',\n    'decimal',\n    'float',\n    'int',\n    'integer',\n    'interval',\n    'nchar',\n    'nclob',\n    'national',\n    'numeric',\n    'real',\n    'row',\n    'smallint',\n    'time',\n    'timestamp',\n    'varchar',\n    'varying', // modifier (character varying)\n    'varbinary'\n  ];\n\n  const NON_RESERVED_WORDS = [\n    \"add\",\n    \"asc\",\n    \"collation\",\n    \"desc\",\n    \"final\",\n    \"first\",\n    \"last\",\n    \"view\"\n  ];\n\n  // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word\n  const RESERVED_WORDS = [\n    \"abs\",\n    \"acos\",\n    \"all\",\n    \"allocate\",\n    \"alter\",\n    \"and\",\n    \"any\",\n    \"are\",\n    \"array\",\n    \"array_agg\",\n    \"array_max_cardinality\",\n    \"as\",\n    \"asensitive\",\n    \"asin\",\n    \"asymmetric\",\n    \"at\",\n    \"atan\",\n    \"atomic\",\n    \"authorization\",\n    \"avg\",\n    \"begin\",\n    \"begin_frame\",\n    \"begin_partition\",\n    \"between\",\n    \"bigint\",\n    \"binary\",\n    \"blob\",\n    \"boolean\",\n    \"both\",\n    \"by\",\n    \"call\",\n    \"called\",\n    \"cardinality\",\n    \"cascaded\",\n    \"case\",\n    \"cast\",\n    \"ceil\",\n    \"ceiling\",\n    \"char\",\n    \"char_length\",\n    \"character\",\n    \"character_length\",\n    \"check\",\n    \"classifier\",\n    \"clob\",\n    \"close\",\n    \"coalesce\",\n    \"collate\",\n    \"collect\",\n    \"column\",\n    \"commit\",\n    \"condition\",\n    \"connect\",\n    \"constraint\",\n    \"contains\",\n    \"convert\",\n    \"copy\",\n    \"corr\",\n    \"corresponding\",\n    \"cos\",\n    \"cosh\",\n    \"count\",\n    \"covar_pop\",\n    \"covar_samp\",\n    \"create\",\n    \"cross\",\n    \"cube\",\n    \"cume_dist\",\n    \"current\",\n    \"current_catalog\",\n    \"current_date\",\n    \"current_default_transform_group\",\n    \"current_path\",\n    \"current_role\",\n    \"current_row\",\n    \"current_schema\",\n    \"current_time\",\n    \"current_timestamp\",\n    \"current_path\",\n    \"current_role\",\n    \"current_transform_group_for_type\",\n    \"current_user\",\n    \"cursor\",\n    \"cycle\",\n    \"date\",\n    \"day\",\n    \"deallocate\",\n    \"dec\",\n    \"decimal\",\n    \"decfloat\",\n    \"declare\",\n    \"default\",\n    \"define\",\n    \"delete\",\n    \"dense_rank\",\n    \"deref\",\n    \"describe\",\n    \"deterministic\",\n    \"disconnect\",\n    \"distinct\",\n    \"double\",\n    \"drop\",\n    \"dynamic\",\n    \"each\",\n    \"element\",\n    \"else\",\n    \"empty\",\n    \"end\",\n    \"end_frame\",\n    \"end_partition\",\n    \"end-exec\",\n    \"equals\",\n    \"escape\",\n    \"every\",\n    \"except\",\n    \"exec\",\n    \"execute\",\n    \"exists\",\n    \"exp\",\n    \"external\",\n    \"extract\",\n    \"false\",\n    \"fetch\",\n    \"filter\",\n    \"first_value\",\n    \"float\",\n    \"floor\",\n    \"for\",\n    \"foreign\",\n    \"frame_row\",\n    \"free\",\n    \"from\",\n    \"full\",\n    \"function\",\n    \"fusion\",\n    \"get\",\n    \"global\",\n    \"grant\",\n    \"group\",\n    \"grouping\",\n    \"groups\",\n    \"having\",\n    \"hold\",\n    \"hour\",\n    \"identity\",\n    \"in\",\n    \"indicator\",\n    \"initial\",\n    \"inner\",\n    \"inout\",\n    \"insensitive\",\n    \"insert\",\n    \"int\",\n    \"integer\",\n    \"intersect\",\n    \"intersection\",\n    \"interval\",\n    \"into\",\n    \"is\",\n    \"join\",\n    \"json_array\",\n    \"json_arrayagg\",\n    \"json_exists\",\n    \"json_object\",\n    \"json_objectagg\",\n    \"json_query\",\n    \"json_table\",\n    \"json_table_primitive\",\n    \"json_value\",\n    \"lag\",\n    \"language\",\n    \"large\",\n    \"last_value\",\n    \"lateral\",\n    \"lead\",\n    \"leading\",\n    \"left\",\n    \"like\",\n    \"like_regex\",\n    \"listagg\",\n    \"ln\",\n    \"local\",\n    \"localtime\",\n    \"localtimestamp\",\n    \"log\",\n    \"log10\",\n    \"lower\",\n    \"match\",\n    \"match_number\",\n    \"match_recognize\",\n    \"matches\",\n    \"max\",\n    \"member\",\n    \"merge\",\n    \"method\",\n    \"min\",\n    \"minute\",\n    \"mod\",\n    \"modifies\",\n    \"module\",\n    \"month\",\n    \"multiset\",\n    \"national\",\n    \"natural\",\n    \"nchar\",\n    \"nclob\",\n    \"new\",\n    \"no\",\n    \"none\",\n    \"normalize\",\n    \"not\",\n    \"nth_value\",\n    \"ntile\",\n    \"null\",\n    \"nullif\",\n    \"numeric\",\n    \"octet_length\",\n    \"occurrences_regex\",\n    \"of\",\n    \"offset\",\n    \"old\",\n    \"omit\",\n    \"on\",\n    \"one\",\n    \"only\",\n    \"open\",\n    \"or\",\n    \"order\",\n    \"out\",\n    \"outer\",\n    \"over\",\n    \"overlaps\",\n    \"overlay\",\n    \"parameter\",\n    \"partition\",\n    \"pattern\",\n    \"per\",\n    \"percent\",\n    \"percent_rank\",\n    \"percentile_cont\",\n    \"percentile_disc\",\n    \"period\",\n    \"portion\",\n    \"position\",\n    \"position_regex\",\n    \"power\",\n    \"precedes\",\n    \"precision\",\n    \"prepare\",\n    \"primary\",\n    \"procedure\",\n    \"ptf\",\n    \"range\",\n    \"rank\",\n    \"reads\",\n    \"real\",\n    \"recursive\",\n    \"ref\",\n    \"references\",\n    \"referencing\",\n    \"regr_avgx\",\n    \"regr_avgy\",\n    \"regr_count\",\n    \"regr_intercept\",\n    \"regr_r2\",\n    \"regr_slope\",\n    \"regr_sxx\",\n    \"regr_sxy\",\n    \"regr_syy\",\n    \"release\",\n    \"result\",\n    \"return\",\n    \"returns\",\n    \"revoke\",\n    \"right\",\n    \"rollback\",\n    \"rollup\",\n    \"row\",\n    \"row_number\",\n    \"rows\",\n    \"running\",\n    \"savepoint\",\n    \"scope\",\n    \"scroll\",\n    \"search\",\n    \"second\",\n    \"seek\",\n    \"select\",\n    \"sensitive\",\n    \"session_user\",\n    \"set\",\n    \"show\",\n    \"similar\",\n    \"sin\",\n    \"sinh\",\n    \"skip\",\n    \"smallint\",\n    \"some\",\n    \"specific\",\n    \"specifictype\",\n    \"sql\",\n    \"sqlexception\",\n    \"sqlstate\",\n    \"sqlwarning\",\n    \"sqrt\",\n    \"start\",\n    \"static\",\n    \"stddev_pop\",\n    \"stddev_samp\",\n    \"submultiset\",\n    \"subset\",\n    \"substring\",\n    \"substring_regex\",\n    \"succeeds\",\n    \"sum\",\n    \"symmetric\",\n    \"system\",\n    \"system_time\",\n    \"system_user\",\n    \"table\",\n    \"tablesample\",\n    \"tan\",\n    \"tanh\",\n    \"then\",\n    \"time\",\n    \"timestamp\",\n    \"timezone_hour\",\n    \"timezone_minute\",\n    \"to\",\n    \"trailing\",\n    \"translate\",\n    \"translate_regex\",\n    \"translation\",\n    \"treat\",\n    \"trigger\",\n    \"trim\",\n    \"trim_array\",\n    \"true\",\n    \"truncate\",\n    \"uescape\",\n    \"union\",\n    \"unique\",\n    \"unknown\",\n    \"unnest\",\n    \"update   \",\n    \"upper\",\n    \"user\",\n    \"using\",\n    \"value\",\n    \"values\",\n    \"value_of\",\n    \"var_pop\",\n    \"var_samp\",\n    \"varbinary\",\n    \"varchar\",\n    \"varying\",\n    \"versioning\",\n    \"when\",\n    \"whenever\",\n    \"where\",\n    \"width_bucket\",\n    \"window\",\n    \"with\",\n    \"within\",\n    \"without\",\n    \"year\",\n  ];\n\n  // these are reserved words we have identified to be functions\n  // and should only be highlighted in a dispatch-like context\n  // ie, array_agg(...), etc.\n  const RESERVED_FUNCTIONS = [\n    \"abs\",\n    \"acos\",\n    \"array_agg\",\n    \"asin\",\n    \"atan\",\n    \"avg\",\n    \"cast\",\n    \"ceil\",\n    \"ceiling\",\n    \"coalesce\",\n    \"corr\",\n    \"cos\",\n    \"cosh\",\n    \"count\",\n    \"covar_pop\",\n    \"covar_samp\",\n    \"cume_dist\",\n    \"dense_rank\",\n    \"deref\",\n    \"element\",\n    \"exp\",\n    \"extract\",\n    \"first_value\",\n    \"floor\",\n    \"json_array\",\n    \"json_arrayagg\",\n    \"json_exists\",\n    \"json_object\",\n    \"json_objectagg\",\n    \"json_query\",\n    \"json_table\",\n    \"json_table_primitive\",\n    \"json_value\",\n    \"lag\",\n    \"last_value\",\n    \"lead\",\n    \"listagg\",\n    \"ln\",\n    \"log\",\n    \"log10\",\n    \"lower\",\n    \"max\",\n    \"min\",\n    \"mod\",\n    \"nth_value\",\n    \"ntile\",\n    \"nullif\",\n    \"percent_rank\",\n    \"percentile_cont\",\n    \"percentile_disc\",\n    \"position\",\n    \"position_regex\",\n    \"power\",\n    \"rank\",\n    \"regr_avgx\",\n    \"regr_avgy\",\n    \"regr_count\",\n    \"regr_intercept\",\n    \"regr_r2\",\n    \"regr_slope\",\n    \"regr_sxx\",\n    \"regr_sxy\",\n    \"regr_syy\",\n    \"row_number\",\n    \"sin\",\n    \"sinh\",\n    \"sqrt\",\n    \"stddev_pop\",\n    \"stddev_samp\",\n    \"substring\",\n    \"substring_regex\",\n    \"sum\",\n    \"tan\",\n    \"tanh\",\n    \"translate\",\n    \"translate_regex\",\n    \"treat\",\n    \"trim\",\n    \"trim_array\",\n    \"unnest\",\n    \"upper\",\n    \"value_of\",\n    \"var_pop\",\n    \"var_samp\",\n    \"width_bucket\",\n  ];\n\n  // these functions can\n  const POSSIBLE_WITHOUT_PARENS = [\n    \"current_catalog\",\n    \"current_date\",\n    \"current_default_transform_group\",\n    \"current_path\",\n    \"current_role\",\n    \"current_schema\",\n    \"current_transform_group_for_type\",\n    \"current_user\",\n    \"session_user\",\n    \"system_time\",\n    \"system_user\",\n    \"current_time\",\n    \"localtime\",\n    \"current_timestamp\",\n    \"localtimestamp\"\n  ];\n\n  // those exist to boost relevance making these very\n  // \"SQL like\" keyword combos worth +1 extra relevance\n  const COMBOS = [\n    \"create table\",\n    \"insert into\",\n    \"primary key\",\n    \"foreign key\",\n    \"not null\",\n    \"alter table\",\n    \"add constraint\",\n    \"grouping sets\",\n    \"on overflow\",\n    \"character set\",\n    \"respect nulls\",\n    \"ignore nulls\",\n    \"nulls first\",\n    \"nulls last\",\n    \"depth first\",\n    \"breadth first\"\n  ];\n\n  const FUNCTIONS = RESERVED_FUNCTIONS;\n\n  const KEYWORDS = [...RESERVED_WORDS, ...NON_RESERVED_WORDS].filter((keyword) => {\n    return !RESERVED_FUNCTIONS.includes(keyword);\n  });\n\n  const VARIABLE = {\n    className: \"variable\",\n    begin: /@[a-z0-9]+/,\n  };\n\n  const OPERATOR = {\n    className: \"operator\",\n    begin: /[-+*/=%^~]|&&?|\\|\\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,\n    relevance: 0,\n  };\n\n  const FUNCTION_CALL = {\n    begin: concat(/\\b/, either(...FUNCTIONS), /\\s*\\(/),\n    keywords: {\n      built_in: FUNCTIONS\n    }\n  };\n\n  // keywords with less than 3 letters are reduced in relevancy\n  function reduceRelevancy(list, {exceptions, when} = {}) {\n    const qualifyFn = when;\n    exceptions = exceptions || [];\n    return list.map((item) => {\n      if (item.match(/\\|\\d+$/) || exceptions.includes(item)) {\n        return item;\n      } else if (qualifyFn(item)) {\n        return `${item}|0`;\n      } else {\n        return item;\n      }\n    });\n  }\n\n  return {\n    name: 'SQL',\n    case_insensitive: true,\n    // does not include {} or HTML tags ` x.length < 3 }),\n      literal: LITERALS,\n      type: TYPES,\n      built_in: POSSIBLE_WITHOUT_PARENS\n    },\n    contains: [\n      {\n        begin: either(...COMBOS),\n        keywords: {\n          $pattern: /[\\w\\.]+/,\n          keyword: KEYWORDS.concat(COMBOS),\n          literal: LITERALS,\n          type: TYPES\n        },\n      },\n      {\n        className: \"type\",\n        begin: either(...MULTI_WORD_TYPES)\n      },\n      FUNCTION_CALL,\n      VARIABLE,\n      STRING,\n      QUOTED_IDENTIFIER,\n      hljs.C_NUMBER_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      COMMENT_MODE,\n      OPERATOR\n    ]\n  };\n}\n\nmodule.exports = sql;\n","/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n  if (!re) return null;\n  if (typeof re === \"string\") return re;\n\n  return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n  return concat('(?=', re, ')');\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction optional(re) {\n  return concat('(', re, ')?');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n  const joined = args.map((x) => source(x)).join(\"\");\n  return joined;\n}\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] } args\n * @returns {string}\n */\nfunction either(...args) {\n  const joined = '(' + args.map((x) => source(x)).join(\"|\") + \")\";\n  return joined;\n}\n\n/*\nLanguage: HTML, XML\nWebsite: https://www.w3.org/XML/\nCategory: common\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction xml(hljs) {\n  // Element names can contain letters, digits, hyphens, underscores, and periods\n  const TAG_NAME_RE = concat(/[A-Z_]/, optional(/[A-Z0-9_.-]*:/), /[A-Z0-9_.-]*/);\n  const XML_IDENT_RE = /[A-Za-z0-9._:-]+/;\n  const XML_ENTITIES = {\n    className: 'symbol',\n    begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/\n  };\n  const XML_META_KEYWORDS = {\n    begin: /\\s/,\n    contains: [\n      {\n        className: 'meta-keyword',\n        begin: /#?[a-z_][a-z1-9_-]+/,\n        illegal: /\\n/\n      }\n    ]\n  };\n  const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {\n    begin: /\\(/,\n    end: /\\)/\n  });\n  const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {\n    className: 'meta-string'\n  });\n  const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {\n    className: 'meta-string'\n  });\n  const TAG_INTERNALS = {\n    endsWithParent: true,\n    illegal: /`]+/\n              }\n            ]\n          }\n        ]\n      }\n    ]\n  };\n  return {\n    name: 'HTML, XML',\n    aliases: [\n      'html',\n      'xhtml',\n      'rss',\n      'atom',\n      'xjb',\n      'xsd',\n      'xsl',\n      'plist',\n      'wsf',\n      'svg'\n    ],\n    case_insensitive: true,\n    contains: [\n      {\n        className: 'meta',\n        begin: //,\n        relevance: 10,\n        contains: [\n          XML_META_KEYWORDS,\n          QUOTE_META_STRING_MODE,\n          APOS_META_STRING_MODE,\n          XML_META_PAR_KEYWORDS,\n          {\n            begin: /\\[/,\n            end: /\\]/,\n            contains: [\n              {\n                className: 'meta',\n                begin: //,\n                contains: [\n                  XML_META_KEYWORDS,\n                  XML_META_PAR_KEYWORDS,\n                  QUOTE_META_STRING_MODE,\n                  APOS_META_STRING_MODE\n                ]\n              }\n            ]\n          }\n        ]\n      },\n      hljs.COMMENT(\n        //,\n        {\n          relevance: 10\n        }\n      ),\n      {\n        begin: //,\n        relevance: 10\n      },\n      XML_ENTITIES,\n      {\n        className: 'meta',\n        begin: /<\\?xml/,\n        end: /\\?>/,\n        relevance: 10\n      },\n      {\n        className: 'tag',\n        /*\n        The lookahead pattern (?=...) ensures that 'begin' only matches\n        ')/,\n        end: />/,\n        keywords: {\n          name: 'style'\n        },\n        contains: [ TAG_INTERNALS ],\n        starts: {\n          end: /<\\/style>/,\n          returnEnd: true,\n          subLanguage: [\n            'css',\n            'xml'\n          ]\n        }\n      },\n      {\n        className: 'tag',\n        // See the comment in the 
+
+
+
+
\ No newline at end of file
diff --git a/src/docs/asciidoc/faq.adoc b/src/docs/asciidoc/faq.adoc
new file mode 100644
index 0000000..f33303a
--- /dev/null
+++ b/src/docs/asciidoc/faq.adoc
@@ -0,0 +1,1120 @@
+[[faq]]
+== F.A.Q
+
+=== How can I define multiple OpenAPI definitions in one Spring Boot project?
+You can define your own groups of API based on the combination of: API paths and packages to scan. Each group should have a unique `groupName`.
+The OpenAPI description of this group, will be available by default on:
+
+* `\http://server:port/context-path/v3/api-docs/groupName`
+
+To enable the support of multiple OpenAPI definitions, a bean of type `GroupedOpenApi` needs to be defined.
+
+For the following Group definition(based on package path), the OpenAPI description URL will be :  /v3/api-docs/**stores**
+
+[source,java]
+----
+@Bean
+public GroupedOpenApi storeOpenApi() {
+   String paths[] = {"/store/**"};
+   return GroupedOpenApi.builder().group("stores").pathsToMatch(paths)
+         .build();
+}
+----
+
+For the following Group definition (based on package name), the OpenAPI description URL will be:  /v3/api-docs/**users**
+
+[source,java]
+----
+@Bean
+public GroupedOpenApi userOpenApi() {
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"};
+   return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan)
+         .build();
+}
+----
+
+For the following Group definition(based on path), the OpenAPI description URL will be:  /v3/api-docs/**pets**
+
+[source,java]
+----
+@Bean
+public GroupedOpenApi petOpenApi() {
+   String paths[] = {"/pet/**"};
+   return GroupedOpenApi.builder().group("pets").pathsToMatch(paths)
+         .build();
+}
+----
+
+For the following Group definition (based on package name and path), the OpenAPI description URL will be:  /v3/api-docs/**groups**
+
+[source,java]
+----
+@Bean
+public GroupedOpenApi groupOpenApi() {
+   String paths[] = {"/v1/**"};
+   String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"};
+   return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan)
+         .build();
+}
+----
+
+For more details about the usage, you can have a look at the following sample Test:
+
+* link:https://github.com/springdoc/springdoc-openapi/tree/main/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/app68[https://github.com/springdoc/springdoc-openapi/tree/main/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/app68, window="_blank"]
+
+=== How can I configure Swagger UI?
+* The support of the swagger official properties is available on `springdoc-openapi`.  See link:https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/[Official documentation, window="_blank"].
+
+* You can use the same swagger properties in the documentation as Spring Boot properties.
+
+NOTE: All these properties should be declared with the following prefix: `springdoc.swagger-ui`
+
+=== How can I filter the resources documented in the output specification by the provided group?
+* You can use the standard `swagger-ui` property filter.
+[source,properties]
+----
+springdoc.swagger-ui.filter=group-a
+----
+
+=== How can I disable/enable Swagger UI generation based on env variable?
+* This property helps you disable only the UI.
+[source,properties]
+----
+springdoc.swagger-ui.enabled=false
+----
+=== How can I control the default expansion setting for the operations and tags, in the Swagger UI ,
+* You can set this property in your application.yml like so for example:
+[source,properties]
+----
+springdoc.swagger-ui.doc-expansion= none
+----
+
+=== How can I change the layout of the `swagger-ui`?
+* For layout options, you can use swagger-ui configuration options. For example:
+[source,properties]
+----
+springdoc.swagger-ui.layout=BaseLayout
+----
+
+=== How can I sort endpoints alphabetically?
+* You can use the following `springdoc-openapi` properties:
+[source,properties]
+----
+#For sorting endpoints alphabetically
+springdoc.swagger-ui.operationsSorter=alpha
+#For sorting tags alphabetically
+springdoc.swagger-ui.tagsSorter=alpha
+----
+
+=== How can I disable the try it out button?
+* You have to set the following property:
+[source,properties]
+----
+springdoc.swagger-ui.supportedSubmitMethods=get, put, post, delete, options, head, patch, trace
+----
+
+=== How can I add  Reusable Enums ?
+* You should add `@Schema(enumAsRef = true)` on your enum.
+
+=== How can i apply `enumAsRef = true` to all enums ?
+* Declare the following property:
+[source,java]
+----
+static {
+    io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true;
+}
+----
+
+=== How can I explicitly set which paths to filter?
+* You can set list of paths to include using the following property:
+[source,properties]
+----
+springdoc.pathsToMatch=/v1, /api/balance/**
+----
+
+=== How can I explicitly set which packages to scan?
+* You can set list of packages to include using the following property:
+[source,properties]
+----
+springdoc.packagesToScan=package1, package2
+----
+
+=== How can I set Swagger properties programmatically?
+
+These can be set by creating a `swaggerUiConfig` bean as follows:
+[source,kotlin]
+----
+@Bean
+@Primary
+fun swaggerUiConfig(config: SwaggerUiConfigProperties): SwaggerUiConfigProperties {
+    config.showCommonExtensions = true
+    config.queryConfigEnabled = true
+    return config
+}
+----
+
+=== How can I ignore some field of model ?
+* You can use the following annotation on the top of the field that you want to hide:
+* `@Schema(hidden = true)`
+
+=== How can I ignore `@AuthenticationPrincipal` parameter from spring-security ?
+* A solution workaround would be to use: `@Parameter(hidden = true)`
+* The projects that use `spring-boot-starter-security` or `spring-security-oauth2-authorization-server`  should use:
+
+- `springdoc-openapi-starter-webmvc-api` if they depend on `spring-boot-starter-web` and they only need the access to the OpenAPI endpoints.
+- OR `springdoc-openapi-starter-webmvc-ui`, if they depend on `spring-boot-starter-web` and they also need the access to the swagger-ui.
+- OR `springdoc-openapi-starter-webflux-api` if they depend on `spring-boot-starter-webflux` and they only the access to the OpenAPI endpoints.
+- OR `springdoc-openapi-starter-webflux-ui`, if they depend on `spring-boot-starter-webflux` and they also need the access to the swagger-ui.
+
+
+
+=== Is there a Gradle plugin available?
+* Yes. More details are available, in the link:https://springdoc.org/#gradle-plugin[gradle plugin] section.
+
+=== How can I hide a parameter from the documentation ?
+* You can use `@Parameter(hidden = true)`
+
+=== Is `@Parameters` annotation supported ?
+* Yes
+
+=== Does `springdoc-openapi` support Jersey?
+* If you are using JAX-RS and as implementation Jersey (`@Path` for example), we do not support it.
+* We only support exposing Rest Endpoints using Spring managed beans (`@RestController` for example).
+* You can have a look at swagger-jaxrs2 project:
+** link:https://github.com/swagger-api/swagger-samples/tree/2.0/java/java-jersey2-minimal[https://github.com/swagger-api/swagger-samples/tree/2.0/java/java-jersey2-minimal, window="_blank"]
+
+=== Can `springdoc-openapi` generate API only for `@RestController`?
+* `@RestController` is equivalent to `@Controller` + `@RequestMapping` on the type level.
+* For some legacy apps, we are constrained to still support both.
+* If you need to hide the `@Controller` on the type level, in this case, you can use: `@Hidden` on controller level.
+* Please note this annotation can be also used to hide some methods from the generated documentation.
+
+=== Are the following validation annotations supported : `@NotEmpty` `@NotBlank` `@PositiveOrZero` `@NegativeOrZero`?
+* Yes
+
+===  How can I map `Pageable` (spring-data-commons) object to correct URL-Parameter in Swagger UI?
+
+The support for Pageable of spring-data-commons is available out-of-the box since `springdoc-openapi v1.6.0`.
+For this, you have to combine `@ParameterObject` annotation with the `Pageable` type.
+
+
+Before `springdoc-openapi v1.6.0`:
+
+* You can use as well `@ParameterObject` instead of `@PageableAsQueryParam` for HTTP `GET` methods.
+
+[source,java]
+----
+static {
+    getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class)
+            .replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class);
+}
+----
+
+* Another solution, is to configure Pageable manually:
+    - you will have to declare the explicit mapping of Pageable fields as Query Params and add the `@Parameter(hidden = true) Pageable pageable` on your pageable parameter.
+    - You should also, declare the annotation `@PageableAsQueryParam` provided by `springdoc-openapi` on the method level, or declare your own if need to define your custom description, defaultValue, ...
+
+If you want to disable the support of spring Pageable Type, you can use:
+[source,properties]
+----
+springdoc.model-converters.pageable-converter.enabled=false
+----
+
+NOTE: The property `springdoc.model-converters.pageable-converter.enabled` is only available since v1.5.11+
+
+=== How can I generate enums in the generated description?
+* You could add a property `allowableValues`, to `@Parameter`. For example:
+
+[source,java]
+----
+@GetMapping("/example")
+public Object example(@Parameter(name ="json", schema = @Schema(description = "var 1",type = "string", allowableValues = {"1", "2"}))
+String json) {
+   return null;
+}
+----
+
+* or you could override `toString` on your enum:
+
+[source,java]
+----
+@Override
+@JsonValue
+public String toString() {
+   return String.valueOf(action);
+}
+----
+
+=== How can I deploy `springdoc-openapi-starter-webmvc-ui` behind a reverse proxy?
+* If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…​) might change along the way. Your application may be running on `10.10.10.10:8080`, but HTTP clients should only see `example.org`.
+
+* link:https://tools.ietf.org/html/rfc7239[RFC7239 "Forwarded Headers", window="_blank"] defines the Forwarded HTTP header; proxies can use this header to provide information about the original request. You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages. There are also non-standard headers, like `X-Forwarded-Host`, `X-Forwarded-Port`, `X-Forwarded-Proto`, `X-Forwarded-Ssl`, and `X-Forwarded-Prefix`.
+
+* If the proxy adds the commonly used `X-Forwarded-For` and `X-Forwarded-Proto headers`, setting server.forward-headers-strategy to NATIVE is enough to support those. With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior.
+
+* You need to make sure the following header is set in your reverse proxy configuration: `X-Forwarded-Prefix`
+* For example, using Apache 2, configuration:
+[source,properties]
+----
+RequestHeader set X-Forwarded-Prefix "/custom-path"
+----
+* Then, in your Spring Boot application make sure your application handles this header: `X-Forwarded-For`. There are two ways to achieve this:
+[source,properties]
+----
+server.use-forward-headers=true
+----
+* If this is not enough, Spring Framework provides a `ForwardedHeaderFilter`. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK.
+* Since Spring Boot 2.2, this is the new property to handle reverse proxy headers:
+
+[source,properties]
+----
+server.forward-headers-strategy=framework
+----
+
+* And you can add the following bean to your application:
+
+[source,java]
+----
+@Bean
+ForwardedHeaderFilter forwardedHeaderFilter() {
+   return new ForwardedHeaderFilter();
+}
+----
+
+* If you need to manually adjust the URL displayed in the Swagger UI, implement the `ServerBaseUrlCustomizer` interface. This might be necessary to remove the port number, for example.
+
+[source,java]
+----
+@Bean
+public class CustomServerBaseUrlCustomizer implements ServerBaseUrlCustomizer {
+    @Override
+    public String customize(String serverBaseUrl) {
+        try {
+            URL url = new URL(serverBaseUrl);
+            if (url.getHost().contains(".com")) {
+                serverBaseUrl = new URL(url.getProtocol(),url.getHost(),url.getFile()).toString();
+            }
+        } catch (MalformedURLException ex) {
+            // nothing we can do
+        }
+
+        return serverBaseUrl;
+    }
+}
+----
+
+===  Is `@JsonView` annotations in Spring MVC APIs supported?
+* Yes
+
+=== Adding `springdoc-openapi-starter-webmvc-ui` dependency breaks my `public/index.html` welcome page
+* If you already have static content on your root, and you don't want it to be overridden by `springdoc-openapi-starter-webmvc-ui` configuration, you can just define a custom configuration of the `swagger-ui`, in order not to override the configuration of your files from in your context-root:
+* For example use:
+[source,properties]
+----
+springdoc.swagger-ui.path= /swagger-ui/api-docs.html
+----
+
+=== How can I test the Swagger UI?
+* You can have a look on this sample test of the UI:
+** link:https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app1/SpringDocApp1Test.java[https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app1/SpringDocApp1Test.java, window="_blank"]
+
+=== How can I customise the OpenAPI object ?
+* You can write your own implementation of `OpenApiCustomizer`.
+* An example is available on:
+** link:https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app39/SpringDocTestApp.java[https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app39/SpringDocTestApp.java, window="_blank"]
+
+[source,java]
+----
+@Bean
+public OpenApiCustomizer consumerTypeHeaderOpenAPICustomizer() {
+return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
+    .forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myConsumerTypeHeader")));
+}
+----
+
+NOTE: This bean `OpenApiCustomizer` will be applied to the Default OpenAPI only.
+
+If you need the `OpenApiCustomizer` to applied to `GroupedOpenApi` as well, then use `GlobalOpenApiCustomizer` instead.
+
+=== How can I return an empty content as response?
+* It is be possible to handle as return an empty content as response using, one of the following syntaxes:
+* `content = @Content`
+* `content = @Content(schema = @Schema(hidden = true))`
+* For example:
+
+[source,java]
+----
+@Operation(summary = "Get thing", responses = {
+      @ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))),
+      @ApiResponse(responseCode = "404", description = "Not found", content = @Content),
+      @ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) })
+@RequestMapping(path = "/testme", method = RequestMethod.GET)
+ResponseEntity testme() {
+   return ResponseEntity.ok("Hello");
+}
+----
+
+=== How are endpoints with multiple consuming media types supported?
+* An overloaded method on the same class, with the same HTTP Method and path, will have as a result, only one OpenAPI Operation generated.
+* In addition, it's recommended to have the `@Operation` in the level of one of the overloaded methods. Otherwise it might be overridden if it's declared many times within the same overloaded method.
+
+=== How can I get yaml and json (OpenAPI) in compile time?
+* You can use `springdoc-openapi-maven-plugin` for this functionality:
+** link:https://github.com/springdoc/springdoc-openapi-maven-plugin.git[https://github.com/springdoc/springdoc-openapi-maven-plugin.git, window="_blank"]
+* You can customise the output directory (property outputDir): The default value is: ${project.build.directory}
+
+=== What are the ignored types in the documentation?
+* `Principal`, `Locale`, `HttpServletRequest` and `HttpServletResponse` and other injectable parameters supported by Spring MVC are excluded.
+* Full documentation here:
+** link:https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments[https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments, window="_blank"]
+
+=== How can i disable ignored types:
+
+If you don't want to ignore the types `Principal`, `Locale`, `HttpServletRequest`, and others,:
+
+[source,java]
+----
+SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class)
+----
+
+
+=== How do I add authorization header in requests?
+* You should add the `@SecurityRequirement` tags to your protected APIs.
+* For example:
+----
+@Operation(security = { @SecurityRequirement(name = "bearer-key") })
+----
+* And the security definition sample:
+
+[source,java]
+----
+@Bean
+ public OpenAPI customOpenAPI() {
+   return new OpenAPI()
+          .components(new Components()
+          .addSecuritySchemes("bearer-key",
+          new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
+}
+----
+
+=== Differentiation to Springfox project
+
+* OAS 3 was released in July 2017, and there was no release of `springfox` to support OAS 3.
+`springfox` covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately.
+
+* We decided to move forward and share the library that we already used on our internal projects, with the community.
+* The biggest difference with `springfox`, is that we integrate new features not covered by `springfox`:
+
+* The integration between Spring Boot and OpenAPI 3 standard.
+* We rely on on `swagger-annotations` and `swagger-ui` only official libraries.
+* We support new features on Spring 5, like `spring-webflux` with annotated and functional style.
+* We do our best to answer all the questions and address all issues or enhancement requests
+
+=== How do I migrate to OpenAPI 3 with springdoc-openapi
+* There is no relation between `springdoc-openapi` and `springfox`.If you want to migrate to OpenAPI 3:
+* Remove all the dependencies and the related code to springfox
+* Add `springdoc-openapi-starter-webmvc-ui` dependency
+* If you don't want to serve the UI from your root path or there is a conflict with an existing configuration, you can just change the following property:
+[source,properties]
+----
+springdoc.swagger-ui.path=/you-path/swagger-ui.html
+----
+
+=== How can I set a global header?
+* You may have global parameters with Standard OpenAPI description.
+* If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.
+* You can define common parameters under parameters in the global components section and reference them elsewhere via `$ref`. You can also define global header parameters.
+* For this, you can override to OpenAPI Bean, and set the global headers or parameters definition on the components level.
+
+[source,java]
+----
+@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+ return new OpenAPI()
+        .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
+        .addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
+        .info(new Info()
+        .title("Petstore API")
+        .version(appVersion)
+        .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
+        .termsOfService("http://swagger.io/terms/")
+        .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+----
+
+=== Are Callbacks supported?
+* Yes
+
+=== How can I define SecurityScheme ?
+* You can use: `@SecurityScheme` annotation.
+* Or you can define it programmatically, by overriding OpenAPI Bean:
+
+[source,java]
+----
+ @Bean
+ public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+  return new OpenAPI()
+   .components(new Components().addSecuritySchemes("basicScheme",
+   new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+   info(new Info().title("SpringShop API").version(appVersion)
+   .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+ }
+----
+
+=== How can I hide an operation or a controller from documentation ?
+* You can use `@io.swagger.v3.oas.annotations.Hidden` annotation at `@RestController`, `@RestControllerAdvice` and method level
+* The `@Hidden` annotation on exception handler methods, is considered when building generic (error) responses from `@ControllerAdvice` exception handlers.
+* Or use: `@Operation(hidden = true)`
+
+
+
+
+=== How to configure global security schemes?
+* For global SecurityScheme, you can add it inside your own OpenAPI definition:
+
+[source,java]
+----
+@Bean
+public OpenAPI customOpenAPI() {
+    return new OpenAPI().components(new Components()
+    .addSecuritySchemes("basicScheme", new SecurityScheme()
+    .type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API")
+    .version("100")).addTagsItem(new Tag().name("mytag"));
+}
+----
+
+===  Can I use spring property with swagger annotations?
+* The support of spring property resolver for `@Info`: `title` * `description` * `version` * `termsOfService`
+* The support of spring property resolver for `@Info.license`: `name` * `url`
+* The support of spring property resolver for `@Info.contact`: `name` * `email` * `url`
+* The support of spring property resolver for `@Operation`: `description` * `summary`
+* The support of spring property resolver for `@Parameter`: `description` * `name`
+* The support of spring property resolver for `@ApiResponse`: `description`
+* Its also possible to declare security URLs for `@OAuthFlow`: `openIdConnectUrl` * `authorizationUrl` * `refreshUrl` * `tokenUrl`
+* The support of spring property resolver for `@Schema`: `name` * `title` * `description` , by setting `springdoc.api-docs.resolve-schema-properties` to `true`
+* The support of spring property resolver for `@ExtensionProperty` by setting `springdoc.api-docs.resolve-extensions-properties` to `true`
+
+===  How is server URL generated ?
+* Generating automatically server URL may be useful, if the documentation is not present.
+* If the server annotations are present, they will be used instead.
+
+=== How can I disable springdoc-openapi cache?
+* By default, the OpenAPI description is calculated once, and then cached.
+* Sometimes the same swagger-ui is served behind internal and external proxies. some users want the server URL, to be computed on each http request.
+* In order to disable springdoc cache, you will have to set the following property:
+[source,properties]
+----
+springdoc.cache.disabled= true
+----
+
+=== How can I expose the mvc api-docs endpoints without using the `swagger-ui`?
+* You should use the `springdoc-openapi-core` dependency only:
+
+[source,xml]
+----
+
+  org.springdoc
+  springdoc-openapi-starter-webmvc-api
+  latest.version
+
+----
+=== How can I disable `springdoc-openapi` endpoints ?
+* Use the following property:
+----
+springdoc.api-docs.enabled=false
+----
+
+=== How can I hide Schema of the the response ?
+
+* To hide the response element, using `@Schema` annotation, as follows, at operation level:
+
+----
+@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))))
+----
+
+* Or directly at `@ApiResponses` level:
+
+----
+@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) })
+OR
+@ApiResponse(responseCode = "404", description = "Not found", content = @Content)
+----
+
+=== What is the URL of the `swagger-ui`, when I set a different context-path?
+
+* If you use different context-path:
+[source,properties]
+----
+server.servlet.context-path= /foo
+----
+* The `swagger-ui` will be available on the following URL:
+** `\http://server:port/foo/swagger-ui.html`
+
+=== Can I customize OpenAPI object programmatically?
+
+* You can Define your own OpenAPI Bean: If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi , you can use OpenAPI Bean.
+
+[source,java]
+----
+@Bean
+public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) {
+   return new OpenAPI()
+    .components(new Components().addSecuritySchemes("basicScheme",
+            new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
+    .info(new Info().title("SpringShop API").version(appVersion)
+            .license(new License().name("Apache 2.0").url("http://springdoc.org")));
+}
+----
+* If you need the definitions to appear within a specific group, and respect the conditions specified on the GroupedOpenApi, you can add OpenApiCustomizer to your GroupedOpenApi definition.
+
+[source,java]
+----
+GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomizer(customerGlobalHeaderOpenApiCustomizer())
+                .build()
+
+@Bean
+public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() {
+   return openApi -> openApi.path("/foo",
+   new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses()
+   .addApiResponse("default",new ApiResponse().description("")
+   .content(new Content().addMediaType("fatz", new MediaType()))))));
+}
+----
+
+
+=== Where can I find the source code of the demo applications?
+* The source code of the application is available at the following GitHub repository:
+** link:https://github.com/springdoc/springdoc-openapi-demos[https://github.com/springdoc/springdoc-openapi-demos, window="_blank"]
+
+=== Does this library supports annotations from interfaces?
+* Yes
+
+=== What is the list of the excluded parameter types?
+* link:https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments[https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments, window="_blank"].
+
+=== Is file upload supported ?
+* The library supports the main file types: `MultipartFile`,  `@RequestPart`, `FilePart`
+* You can upload a file as follows:
+
+[source,java]
+----
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Encoding;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+
+@PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+public ResponseEntity upload(@Parameter(description = "file") final MultipartFile file) {
+    return null;
+}
+
+@PostMapping(value = "/uploadFileWithQuery", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
+public ResponseEntity uploadFileWithQuery(@Parameter(description = "file") @RequestPart("file") final MultipartFile file,
+        @Parameter(description = "An extra query parameter") @RequestParam String name) {
+    return null;
+}
+
+@PostMapping(value = "/uploadFileWithJson", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = {
+        MediaType.APPLICATION_JSON_VALUE})
+public ResponseEntity uploadFileWithJson(
+        @RequestBody(content = @Content(encoding = @Encoding(name = "jsonRequest", contentType = MediaType.APPLICATION_JSON_VALUE)))
+        @Parameter(description = "An extra JSON payload sent with file") @RequestPart("jsonRequest") final JsonRequest jsonRequest,
+        @RequestPart("file") final MultipartFile file) {
+    return null;
+}
+----
+
+=== Can I use `@Parameter` inside `@Operation` annotation?
+* Yes, it's supported
+
+=== Why my parameter is marked as required?
+* Any `@GetMapping` parameters is marked as required, even if `@RequestParam` is missing.
+* You can add `@Parameter(required=false)` annotation if you need different behaviour.
+* Query parameters with `defaultValue` specified are marked as required.
+
+=== How are overloaded methods with the same endpoints, but with different parameters
+* `springdoc-openapi` renders these methods as a single endpoint. It detects the overloaded endpoints, and generates parameters.schema.oneOf.
+
+=== What is a proper way to set up Swagger UI to use provided spec.yml?
+* With this property, all the `springdoc-openapi` auto-configuration beans are disabled:
+[source,properties]
+----
+springdoc.api-docs.enabled=false
+----
+* Then enable the minimal Beans configuration, by adding this Bean:
+
+[source,java]
+----
+@Bean
+SpringDocConfiguration springDocConfiguration(){
+   return new SpringDocConfiguration();
+}
+
+@Bean
+SpringDocConfigProperties springDocConfigProperties() {
+   return new SpringDocConfigProperties();
+}
+
+@Bean
+ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){
+    return new ObjectMapperProvider(springDocConfigProperties);
+}
+----
+
+* Then configure, the path of your custom UI yaml file.
+[source,properties]
+----
+springdoc.swagger-ui.url=/api-docs.yaml
+----
+
+=== Is there a way to send authorization header through the @Parameter tag?
+* The OpenAPI 3 specification does not allow explicitly adding Authorization header.
+`Note: Header parameters named Accept, Content-Type and Authorization are not allowed. To describe these headers`
+* For more information, you can read:
+** link:https://swagger.io/docs/specification/describing-parameters/#header-parameters[https://swagger.io/docs/specification/describing-parameters/#header-parameters, window="_blank"]
+
+=== My Rest Controller using @Controller annotation is ignored?
+* This is the default behaviour if your `@Controller` doesn't have annotation `@ResponseBody`
+* You can change your controllers to `@RestControllers`. Or add `@ResponseBody` + `@Controller`.
+* If its not possible, you can configure springdoc to scan you additional controller using SpringDocUtils. For example:
+
+[source,java]
+----
+static {
+   SpringDocUtils.getConfig().addRestControllers(HelloController.class);
+}
+----
+
+=== How can I define groups using application.yml?
+* You can load groups dynamically using spring-boot configuration files.
+* Note that, for this usage, you don't have to declare the **GroupedOpenApi** Bean.
+* You need to declare the following properties, under the prefix **springdoc.group-configs**.
+* For example:
+[source,properties]
+----
+springdoc.group-configs[0].group=users
+springdoc.group-configs[0].paths-to-match=/user/**
+springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api
+----
+* The list of properties under this prefix, are available here:
+** link:index.html#properties[springdoc-openapi-properties]
+
+=== How can I extract fields from parameter object ?
+* You can use springdoc annotation @ParameterObject.
+* Request parameter annotated with @ParameterObject will help adding each field of the parameter as a separate request parameter.
+* This is compatible with Spring MVC request parameters mapping to POJO object.
+* This annotation does not support nested parameter objects.
+* POJO object must contain getters for fields with mandatory prefix `get`. Otherwise, the swagger documentation will not show the fields of the annotated entity.
+
+=== How can I use the last `springdoc-openapi` SNAPSHOT ?
+* For testing purposes only, you can test temporarily using the last `springdoc-openapi` SNAPSHOT
+* To achieve that, configure your pom.xml file with the following `` section:
+
+[source,xml]
+----
+    
+      
+        Central Portal Snapshots
+        central-portal-snapshots
+        https://central.sonatype.com/repository/maven-snapshots/
+        
+          false
+        
+        
+          true
+        
+      
+    
+----
+
+=== How can I use enable `springdoc-openapi` MonetaryAmount support ?
+* If an application wants to enable the `springdoc-openapi` support, it declares:
+
+[source,java]
+----
+SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class);
+----
+
+* Another solution, without using springdoc-openapi MonetaryAmount, would be:
+
+[source,java]
+----
+SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema()
+            .addProperties("amount", new NumberSchema()).example(99.96)
+            .addProperties("currency", new StringSchema().example("USD")));
+----
+
+=== How can i aggregate external endpoints (exposing OPENAPI 3 spec) inside one single application?
+The properties `springdoc.swagger-ui.urls.*`, are suitable to configure external (/v3/api-docs url).
+For example if you want to agreagte all the endpoints of other services, inside one single application.
+IMPORTANT: Don't forget that CORS needs to be enabled as well.
+
+=== How can use custom json/yml file instead of generated one ?
+If your file open-api.json, contains the OpenAPI documentation in OpenAPI 3 format.
+Then simply declare: The file name can be anything you want, from the moment your declaration is consistent yaml or json OpenAPI Spec.
+[source,properties]
+----
+   springdoc.swagger-ui.url=/open-api.json
+----
+
+Then the file open-api.json, should be located in: src/main/resources/static
+No additional configuration is needed.
+
+=== How can i enable CSRF support?
+If you are using standard headers.( For example using spring-security headers)
+If the CSRF Token is required, swagger-ui automatically sends the new XSRF-TOKEN during each HTTP REQUEST.
+
+If your XSRF-TOKEN isn't standards-based, you can use a requestInterceptor to manually capture and attach the latest xsrf token to requests programmatically via spring resource transformer:
+
+* link:https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md#requestinterceptor[https://github.com/swagger-api/swagger-ui/blob/main/docs/usage/configuration.md#requestinterceptor, window="_blank"]
+
+Starting from release v1.4.4 of springdoc-openapi, a new property is added to enable CSRF support, while using standard header names:
+[source,properties]
+----
+springdoc.swagger-ui.csrf.enabled=true
+----
+
+=== How can i disable the default swagger petstore URL?
+You can use the following property:
+[source,properties]
+----
+springdoc.swagger-ui.disable-swagger-default-url=true
+----
+
+=== Is @PageableDefault supported, to enhance the OpenAPI 3 docuementation?
+Yes, you can use it in conjunction with  `@ParameterObject` annotation.
+Also, the spring-boot `spring.data.web.*` and `spring.data.rest.default.*` properties are supported since v1.4.5
+
+=== How can i make spring security login-endpoint visible ?
+You can use the following property:
+[source,properties]
+----
+springdoc.show-login-endpoint=true
+----
+
+=== How can i show schema definitions even the schema is not referenced?
+You can use the following property:
+[source,properties]
+----
+springdoc.remove-broken-reference-definitions=false
+----
+
+=== How to override @Deprecated?
+The whole idea of `springdoc-openapi` is to get your documentation the closest to the code, with minimal code changes.
+If the code contains `@Deprecated`, `sprindoc-openapi` will consider its schema as Deprecated as well.
+If you want to declare a field on swagger as non deprecated, even with the java code, the field contains `@Depreacted`,
+You can use the following property that is available since release v1.4.3:
+[source,properties]
+----
+springdoc.model-converters.deprecating-converter.enabled=false
+----
+
+=== How can i display a method that returns ModelAndView?
+
+You can use the following property:
+[source,properties]
+----
+springdoc.model-and-view-allowed=true
+----
+
+
+=== How can i have pretty-printed output of the OpenApi specification?
+
+You can use the following property:
+[source,properties]
+----
+springdoc.writer-with-default-pretty-printer=true
+----
+
+=== How can i define different schemas for the same class?
+Complex objects are always resolved as a reference to a schema defined in components.
+For example let's consider a `Instance` class with an `workAddress` and `homeAddress` attribute of type `Address`:
+
+[source,java]
+----
+public class PersonDTO {
+
+	@JsonProperty
+	private String email;
+
+	@JsonProperty
+	private String firstName;
+
+	@JsonProperty
+	private String lastName;
+
+	@Schema(ref = "WorkAddressSchema")
+	@JsonProperty
+	private Address workAddress;
+
+	@Schema(ref = "HomeAddressSchema")
+	@JsonProperty
+	private Address homeAddress;
+
+}
+
+public class Address {
+
+	@JsonProperty
+	private String addressName;
+
+}
+----
+
+If you want to define two different schemas for this class, you can set up 2 different schemas as follow:
+
+[source,java]
+----
+@Bean
+public OpenAPI customOpenAPI() {
+return new OpenAPI().components(new Components()
+.addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address" ))
+.addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address" )));
+}
+
+private Schema getSchemaWithDifferentDescription(Class className, String description){
+ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+.resolveAsResolvedSchema(
+new AnnotatedType(className).resolveAsRef(false));
+return resolvedSchema.schema.description(description);
+}
+----
+
+=== How can i define different description for a class attribute depending on usage?
+For example let's consider a `Instance` class with an `email` attribute:
+
+[source,java]
+----
+public class PersonDTO {
+
+	@JsonProperty
+	private String email;
+
+	@JsonProperty
+	private String firstName;
+
+	@JsonProperty
+	private String lastName;
+
+
+}
+----
+
+If you want to define two different description for the  `email`, you can set up 2 different schemas as follow:
+
+[source,java]
+----
+@Bean
+public OpenAPI customOpenAPI() {
+return new OpenAPI().components(new Components()
+.addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email" ))
+.addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email" )));
+}
+
+private Schema getFieldSchemaWithDifferentDescription(Class className, String description){
+    ResolvedSchema resolvedSchema = ModelConverters.getInstance()
+            .resolveAsResolvedSchema(
+                    new AnnotatedType(className).resolveAsRef(false));
+    return resolvedSchema.schema.addProperties("email", new StringSchema().description(description));
+}
+----
+
+=== Customizing swagger static resources
+
+You can customize swagger documentation static resources located in `META-INF/resources/webjars/swagger-ui/{swagger.version}/`. The list of resources includes:
+
+- `index.html`
+- `swagger-ui-bundle.js`
+- `swagger-ui.css`
+- `swagger-ui-standalone-preset.js`
+- `swagger-ui.css.map`
+- `swagger-ui-bundle.js.map`
+- `swagger-ui-standalone-preset.js.map`
+- `favicon-32x32.png`
+
+To do this, you need to extend the implementation of `SwaggerIndexPageTransformer`
+
+[source,java]
+----
+public class SwaggerCodeBlockTransformer
+       extends SwaggerIndexPageTransformer {
+  // < constructor >
+  @Override
+  public Resource transform(HttpServletRequest request,
+                            Resource resource,
+                            ResourceTransformerChain transformer)
+                            throws IOException {
+      if (resource.toString().contains("swagger-ui.css")) {
+          final InputStream is = resource.getInputStream();
+          final InputStreamReader isr = new InputStreamReader(is);
+          try (BufferedReader br = new BufferedReader(isr)) {
+              final String css = br.lines().collect(Collectors.joining());
+              final byte[] transformedContent = css.replace("old", "new").getBytes();
+              return  new TransformedResource(resource, transformedContent);
+          } // AutoCloseable br > isr > is
+      }
+      return super.transform(request, resource, transformer);
+  }
+
+}
+----
+
+Next, add transformer `@Bean` to your `@Configuration`
+
+[source,java]
+----
+@Configuration
+public class OpenApiConfig {
+    @Bean
+    public SwaggerIndexTransformer swaggerIndexTransformer(
+            SwaggerUiConfigProperties a,
+            SwaggerUiOAuthProperties b,
+            SwaggerUiConfigParameters c,
+            SwaggerWelcomeCommon d) {
+        return new SwaggerCodeBlockTransformer(a, b, c, d);
+    }
+}
+----
+
+Illustrative example
+
+image::img/static_content_transformation.png[Illustrative example]
+
+=== Is GraalVM supported ?
+The native support available added in spring-boot 3.
+If you have some time, do not hesitate to test it before the next release.
+
+For the OpenAPI REST endpoints, you just need to build your application with the spring `native` profile.
+
+If you give `@OpenAPIDefinition` or `@SecurityScheme` to a class that has no implementation, that class will disappear when you natively compile.
+To avoid this, give the class a `@Configuration`.
+----
+@Configuration
+@OpenAPIDefinition(info = @Info(title = "My App", description = "description"))
+public class OpenAPIConfig {
+}
+----
+
+=== How to Integrate Open API 3 with Spring project (not Spring Boot)?
+When your application is using spring without (spring-boot), you need to add beans and  auto-configuration that are natively provided in spring-boot.
+
+For example, lets assume you want load the swagger-ui in spring-mvc application:
+
+* You mainly, need to add the springdoc-openapi module
+
+[source,xml]
+----
+
+   org.springdoc
+   springdoc-openapi-starter-webmvc-ui
+   last.version
+
+----
+
+* If you don't have the spring-boot and spring-boot-autoconfigure dependencies, you need to add them. And pay attention to the compatibility matrix, between you spring.version and spring-boot.version. For example, in this case (spring.version=5.1.12.RELEASE):
+
+[source,xml]
+----
+		
+			org.springframework.boot
+			spring-boot-autoconfigure
+			3.3.3
+		
+----
+
+* Scan for the `springdoc-openapi` 'auto-configuration classes that spring-boot automatically loads for you.
+* Depending on your module, you can find them on the file: `spring.factories` of each `springdoc-openapi` module.
+
+[source,java]
+----
+@Configuration
+@EnableWebMvc
+public class WebConfig implements WebApplicationInitializer {
+
+	@Override
+	public void onStartup(ServletContext servletContext)  {
+		WebApplicationContext context = getContext();
+		servletContext.addListener(new ContextLoaderListener(context));
+		ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet",
+				new DispatcherServlet(context));
+		dispatcher.setLoadOnStartup(1);
+		dispatcher.addMapping("/*");
+	}
+
+	private AnnotationConfigWebApplicationContext getContext() {
+		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+		context.register(this.getClass(),
+				SpringDocConfiguration.class,
+				SpringDocConfigProperties.class,
+				SpringDocSpecPropertiesConfiguration.class,
+				SpringDocWebMvcConfiguration.class, 
+				MultipleOpenApiSupportConfiguration.class,
+				SwaggerConfig.class,
+				SwaggerUiConfigProperties.class,
+				SwaggerUiOAuthProperties.class,
+		);
+		return context;
+	}
+}
+----
+
+* Depending on your module, you can find them on the file: `org.springframework.boot.autoconfigure.AutoConfiguration.imports` of each `springdoc-openapi` module.
+* For groups usage make sure your  `GroupedOpenApi` Beans are scanned.
+* If additionally, you are using custom `context path`: `/my-servlet-path`. Make sure you declare the following property:
+[source,properties]
+----
+spring.mvc.servlet.path=/my-servlet-path
+----
+
+=== What is the compatibility matrix of `springdoc-openapi` with `spring-boot` ?
+`springdoc-openapi 2.x` is compatible with `spring-boot 3`.
+
+In general, **you should only pick the last stable version as per today {springdoc-version}.**
+
+More precisely, this the exhaustive list of spring-boot versions against which `springdoc-openapi` has been built:
+
+|===
+| Spring Boot Versions | Springdoc OpenAPI Versions
+|`3.4.x` | `2.7.x` - `2.8.x`
+|`3.3.x` | `2.6.x`
+|`3.2.x` | `2.3.x` - `2.5.x`
+|`3.1.x` | `2.2.x`
+|`3.0.x` | `2.0.x` - `2.1.x`
+|`2.7.x`, `1.5.x` | `1.6.0`+
+|`2.6.x`, `1.5.x` | `1.6.0`+
+|`2.5.x`, `1.5.x` | `1.5.9`+
+|`2.4.x`, `1.5.x` | `1.5.0`+
+|`2.3.x`, `1.5.x` | `1.4.0`+
+|`2.2.x`, `1.5.x` | `1.2.1`+
+|`2.0.x`, `1.5.x` | `1.0.0`+
+
+|===
+
+
+=== Why am i getting an error: `Swagger UI unable to render definition`, when overriding the default spring registered `HttpMessageConverter`?
+When overriding the default spring-boot registered `HttpMessageConverter`, you should have `ByteArrayHttpMessageConverter` registered as well to have proper `springdoc-openapi` support.
+
+[source,java]
+----
+    converters.add(new ByteArrayHttpMessageConverter());
+    converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder.build()));
+----
+NOTE:  Order is very important, when registering `HttpMessageConverters`.
+
+=== Some parameters are not generated in the resulting OpenAPI spec.
+
+The issue is caused by the changes introduced by link:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes[Spring-Boot 3.2.0, window="_blank"]
+in particular for the **Parameter Name Discovery**.
+This can be fixed by adding the `-parameters` arg to the Maven Compiler Plugin.
+
+[source,xml, subs="attributes+"]
+----
+
+    org.apache.maven.plugins
+    maven-compiler-plugin
+    
+        true
+    
+
+----
+
diff --git a/src/docs/asciidoc/favicon.ico b/src/docs/asciidoc/favicon.ico
new file mode 100644
index 0000000..45468e6
Binary files /dev/null and b/src/docs/asciidoc/favicon.ico differ
diff --git a/src/docs/asciidoc/features.adoc b/src/docs/asciidoc/features.adoc
new file mode 100644
index 0000000..34e8863
--- /dev/null
+++ b/src/docs/asciidoc/features.adoc
@@ -0,0 +1,194 @@
+[[features]]
+== Springdoc-openapi Features
+
+=== Adding API Information and Security documentation
+The library uses spring-boot application auto-configured packages to scan for the following annotations in spring beans: OpenAPIDefinition and Info.
+These annotations declare, API Information: Title, version, licence, security, servers, tags, security and externalDocs.
+For better performance of documentation generation, declare @OpenAPIDefinition and @SecurityScheme annotations within a spring managed bean.
+
+=== Error Handling for REST using @ControllerAdvice
+To generate documentation automatically, make sure all the methods declare the HTTP Code responses using the annotation: @ResponseStatus
+
+=== Disabling the `springdoc-openapi` endpoints
+In order to disable the `springdoc-openapi` endpoint (/v3/api-docs by default) use the following property:
+[source,properties]
+----
+# Disabling the /v3/api-docs endpoint
+springdoc.api-docs.enabled=false
+----
+
+=== Disabling the swagger-ui
+In order to disable the swagger-ui, use the following property:
+[source,properties]
+----
+# Disabling the swagger-ui
+springdoc.swagger-ui.enabled=false
+----
+
+=== Swagger-ui configuration
+The library supports the swagger-ui official properties:
+
+* link:https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/[https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/, window="_blank"]
+
+You need to declare swagger-ui properties as spring-boot properties.
+All these properties should be declared with the following prefix: **springdoc.swagger-ui**
+
+=== Selecting the Rest Controllers to include in the documentation
+Additionally, to @Hidden annotation from swagger-annotations, its possible to restrict the generated OpenAPI description using package or path configuration.
+
+For the list of packages to include, use the following property:
+[source,properties]
+----
+# Packages to include
+springdoc.packagesToScan=com.package1, com.package2
+----
+
+For the list of paths to include, use the following property:
+[source,properties]
+----
+# Paths to include
+springdoc.pathsToMatch=/v1, /api/balance/**
+----
+
+=== Spring-webflux/WebMvc.fn with Functional Endpoints
+Since version v1.5.0, a functional DSL has been introduced, thanks to this enhancement in the spring-framework: link:https://github.com/spring-projects/spring-framework/issues/25938[#25938]
+
+It's an alternative functional API to the `@RouterOperations` annotations.
+
+This is a sample DSL, to generate OpenAPI description to the webflux/WebMvc.fn REST endpoints:
+
+[source,java]
+----
+@Bean
+RouterFunction routes() {
+    return route().GET("/foo", HANDLER_FUNCTION, ops -> ops
+            .operationId("hello")
+            .parameter(parameterBuilder().name("key1").description("My key1 description"))
+            .parameter(parameterBuilder().name("key2").description("My key2 description"))
+            .response(responseBuilder().responseCode("200").description("This is normal response description"))
+            .response(responseBuilder().responseCode("404").description("This is another response description"))
+    ).build();
+}
+----
+
+Here is the link for some sample codes:
+
+- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app90/HelloRouter.java[HelloRouter]
+- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app90/quotes/QuotesRouter.java[QuotesRouter]
+- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app90/book/BookRouter.java[BookRouter]
+- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app90/employee/EmployeeRouter.java[EmployeeRouter]
+- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/app90/position/PositionRouter.java[PositionRouter]
+
+And the Demo code, using the functional endpoints DSL:
+
+- link:https://github.com/springdoc/springdoc-openapi-demos/tree/master/demo-spring-boot-3-webflux-functional[Sample webflux application using functional DSL]
+
+Since version `v1.3.8`, the support of functional endpoints has been added.
+Two main annotations have been added for this purpose: `@RouterOperations` and `@RouterOperation`.
+
+Only REST APIs with the `@RouterOperations` and `@RouterOperation` can be displayed on the swagger-ui.
+
+*   `@RouterOperation`: It can be used alone, if the Router bean contains one single route related to the REST API..
+When using @RouterOperation, its not mandatory to fill the path
+
+*   `@RouterOperation`, can reference directly a spring Bean (beanClass property) and the underlying method (beanMethod property): Springdoc-openapi, will then inspect this method and the swagger annotations on this method level.
+
+[source,java]
+----
+@Bean
+@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees")
+RouterFunction getAllEmployeesRoute() {
+   return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)),
+         req -> ok().body(
+               employeeService().findAllEmployees(), Employee.class));
+}
+----
+
+*   `@RouterOperation`, contains the `@Operation` annotation.
+The `@Operation` annotation can also be placed on the bean method level if the property beanMethod is declared.
+
+IMPORTANT:   Don't forget to set **operationId** which is **mandatory**.
+
+[source,java]
+----
+@Bean
+@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" },
+      parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") },
+      responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))),
+            @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"),
+            @ApiResponse(responseCode = "404", description = "Employee not found") }))
+RouterFunction getEmployeeByIdRoute() {
+   return route(GET("/employees/{id}"),
+         req -> ok().body(
+               employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
+}
+----
+
+*   `@RouterOperations`: This annotation should be used if the Router bean contains multiple routes.
+When using RouterOperations, its mandatory to fill the path property.
+
+*   A `@RouterOperations`, contains many `@RouterOperation`.
+
+[source,java]
+----
+@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
+      @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
+      @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
+      @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
+@Bean
+public RouterFunction personRoute(PersonHandler handler) {
+   return RouterFunctions
+         .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
+         .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
+         .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
+         .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
+}
+----
+
+All the documentations filled using @RouterOperation, might be completed by the router function data.
+For that, `@RouterOperation` fields must help identify uniquely the concerned route.
+`springdoc-openpi` scans for a unique route related to a `@RouterOperation` annotation, using on the following criteria:
+
+* by path
+* by path and RequestMethod
+* by path and produces
+* by path and consumes
+* by path and RequestMethod and produces
+* by path and RequestMethod and consumes
+* by path and produces and consumes
+* by path and RequestMethod and produces and consumes
+
+Some code samples are available on GITHUB of demos:
+
+* link:https://github.com/springdoc/springdoc-openapi-demos/tree/master/demo-spring-boot-3-webflux-functional[Sample application with Functional Endpoints documentation, window="_blank"]
+
+And some project tests: (from app69 to app75)
+
+* link:https://github.com/springdoc/springdoc-openapi/tree/master/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api[Sample code with Functional Endpoints documentation, window="_blank"]
+
+=== Integration with WildFly
+
+*   For WildFly users, you need to add the following dependency to make the swagger-ui work:
+
+[source,xml]
+----
+   
+     org.webjars
+     webjars-locator-jboss-vfs
+     0.1.0
+   
+----
+
+++++
+
+
+
+++++
\ No newline at end of file
diff --git a/src/docs/asciidoc/getting-started.adoc b/src/docs/asciidoc/getting-started.adoc
new file mode 100644
index 0000000..8bc4a06
--- /dev/null
+++ b/src/docs/asciidoc/getting-started.adoc
@@ -0,0 +1,46 @@
+[[getting-started]]
+== Getting Started
+
+For the integration between spring-boot and swagger-ui, add the library to the list of your project dependencies (No additional configuration is needed)
+
+[source,xml, subs="attributes+"]
+----
+   
+      org.springdoc
+      springdoc-openapi-starter-webmvc-ui
+      {springdoc-version}
+   
+----
+
+
+This will automatically deploy swagger-ui to a spring-boot application:
+
+*   Documentation will be available in HTML format, using the official link:https://github.com/swagger-api/swagger-ui.git[swagger-ui jars, window="_blank"]
+*   The Swagger UI page will then be available at `\http://server:port/context-path/swagger-ui.html` and the OpenAPI description will be available at the following url for json format: `\http://server:port/context-path/v3/api-docs`
+**  server: The server name or IP
+**  port: The server port
+**  context-path: The context path of the application
+*   Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml
+
+TIP: For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: .
+
+
+[source,properties]
+----
+# swagger-ui custom path
+springdoc.swagger-ui.path=/swagger-ui.html
+----
+
+++++
+
+
+
+++++
\ No newline at end of file
diff --git a/src/docs/asciidoc/img/LVM_Versicherung_2010_logo.svg.png b/src/docs/asciidoc/img/LVM_Versicherung_2010_logo.svg.png
new file mode 100644
index 0000000..5aac7e9
Binary files /dev/null and b/src/docs/asciidoc/img/LVM_Versicherung_2010_logo.svg.png differ
diff --git a/src/docs/asciidoc/img/banner-logo.svg b/src/docs/asciidoc/img/banner-logo.svg
new file mode 100644
index 0000000..aeb97b5
--- /dev/null
+++ b/src/docs/asciidoc/img/banner-logo.svg
@@ -0,0 +1,85 @@
+
+
+
+
+
+Created with Fabric.js 4.6.0
+
+
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+		
+
+
+
+
+
+		OpenAPI 3&Spring Boot
+
+
\ No newline at end of file
diff --git a/src/docs/asciidoc/img/common.jpg b/src/docs/asciidoc/img/common.jpg
new file mode 100644
index 0000000..22a2138
Binary files /dev/null and b/src/docs/asciidoc/img/common.jpg differ
diff --git a/src/docs/asciidoc/img/common.png b/src/docs/asciidoc/img/common.png
new file mode 100644
index 0000000..0fc4efe
Binary files /dev/null and b/src/docs/asciidoc/img/common.png differ
diff --git a/src/docs/asciidoc/img/contrastsecurity.svg b/src/docs/asciidoc/img/contrastsecurity.svg
new file mode 100644
index 0000000..21cd538
--- /dev/null
+++ b/src/docs/asciidoc/img/contrastsecurity.svg
@@ -0,0 +1,17 @@
+
+
+    Contrast_Logo_RGB
+    
+        
+            
+                
+                
+                
+                    
+                    
+                    
+                
+            
+        
+    
+
\ No newline at end of file
diff --git a/src/docs/asciidoc/img/dmTECH_Logo.jpg b/src/docs/asciidoc/img/dmTECH_Logo.jpg
new file mode 100644
index 0000000..470b6fb
Binary files /dev/null and b/src/docs/asciidoc/img/dmTECH_Logo.jpg differ
diff --git a/src/docs/asciidoc/img/gdnext.png b/src/docs/asciidoc/img/gdnext.png
new file mode 100644
index 0000000..1523834
Binary files /dev/null and b/src/docs/asciidoc/img/gdnext.png differ
diff --git a/src/docs/asciidoc/img/github-logo.png b/src/docs/asciidoc/img/github-logo.png
new file mode 100644
index 0000000..8b25551
Binary files /dev/null and b/src/docs/asciidoc/img/github-logo.png differ
diff --git a/src/docs/asciidoc/img/mercedes-benz.png b/src/docs/asciidoc/img/mercedes-benz.png
new file mode 100644
index 0000000..38a46ef
Binary files /dev/null and b/src/docs/asciidoc/img/mercedes-benz.png differ
diff --git a/src/docs/asciidoc/img/pets.png b/src/docs/asciidoc/img/pets.png
new file mode 100644
index 0000000..f14c9fe
Binary files /dev/null and b/src/docs/asciidoc/img/pets.png differ
diff --git a/src/docs/asciidoc/img/spring-io-24.png b/src/docs/asciidoc/img/spring-io-24.png
new file mode 100644
index 0000000..4aca7cf
Binary files /dev/null and b/src/docs/asciidoc/img/spring-io-24.png differ
diff --git a/src/docs/asciidoc/img/springdoc-openapi-conf.gif b/src/docs/asciidoc/img/springdoc-openapi-conf.gif
new file mode 100644
index 0000000..2dd4118
Binary files /dev/null and b/src/docs/asciidoc/img/springdoc-openapi-conf.gif differ
diff --git a/src/docs/asciidoc/img/springdoc-openapi-prez.gif b/src/docs/asciidoc/img/springdoc-openapi-prez.gif
new file mode 100644
index 0000000..8b4ff47
Binary files /dev/null and b/src/docs/asciidoc/img/springdoc-openapi-prez.gif differ
diff --git a/src/docs/asciidoc/img/springdoc-openapi.png b/src/docs/asciidoc/img/springdoc-openapi.png
new file mode 100644
index 0000000..a244f90
Binary files /dev/null and b/src/docs/asciidoc/img/springdoc-openapi.png differ
diff --git a/src/docs/asciidoc/img/springdoc/springdoc-favicon.svg b/src/docs/asciidoc/img/springdoc/springdoc-favicon.svg
new file mode 100644
index 0000000..21eeef6
--- /dev/null
+++ b/src/docs/asciidoc/img/springdoc/springdoc-favicon.svg
@@ -0,0 +1,166 @@
+
+
+
+
Created with Fabric.js 4.6.0




		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		




































diff --git a/src/docs/asciidoc/img/springdoc/springdoc-logo.svg b/src/docs/asciidoc/img/springdoc/springdoc-logo.svg
new file mode 100644
index 0000000..f3f7bb8
--- /dev/null
+++ b/src/docs/asciidoc/img/springdoc/springdoc-logo.svg
@@ -0,0 +1,139 @@
+
+
+
+
Created with Fabric.js 4.6.0




		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		




































diff --git a/src/docs/asciidoc/img/static_content_transformation.png b/src/docs/asciidoc/img/static_content_transformation.png
new file mode 100644
index 0000000..edcc70d
Binary files /dev/null and b/src/docs/asciidoc/img/static_content_transformation.png differ
diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc
new file mode 100644
index 0000000..332cab8
--- /dev/null
+++ b/src/docs/asciidoc/index.adoc
@@ -0,0 +1,57 @@
+= springdoc-openapi v{springdoc-version}
+include::_attributes.adoc[]
+
+IMPORTANT: ``springdoc-openapi v1.8.0 `` is the latest Open Source release supporting Spring Boot 2.x and 1.x. +
+An extended support for https://springdoc.org/v1[*springdoc-openapi v1*] project is now available for organizations that need support beyond 2023. +
+For more details, feel free to reach out: sales@springdoc.org
+
+`springdoc-openapi` is on link:https://opencollective.com/springdoc[Open Collective, window="_blank"]. If you ❤️ this project consider becoming a link:https://github.com/sponsors/springdoc[sponsor, window="_blank"].
+
+This project is sponsored by
+++++
+        

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

+++++ + +link:https://github.com/springdoc/springdoc-openapi[View project on GitHub, window="_blank"] image:img/github-logo.png[link="https://github.com/springdoc/springdoc-openapi"] + +include::intro.adoc[] + +include::getting-started.adoc[] + +include::modules.adoc[] + +include::features.adoc[] + +include::properties.adoc[] + +include::plugins.adoc[] + +include::demos.adoc[] + +include::migrating-from-springdoc-v1.adoc[] + +include::migrating-from-springfox.adoc[] + +include::other-resources.adoc[] + +include::sponsor.adoc[] + +include::thanks.adoc[] + +include::faq.adoc[] diff --git a/src/docs/asciidoc/intro.adoc b/src/docs/asciidoc/intro.adoc new file mode 100644 index 0000000..5859101 --- /dev/null +++ b/src/docs/asciidoc/intro.adoc @@ -0,0 +1,28 @@ +[[Introduction]] +== Introduction + + +`springdoc-openapi` java library helps to automate the generation of API documentation using spring boot projects. +`springdoc-openapi` works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations. + +Automatically generates documentation in JSON/YAML and HTML format APIs. +This documentation can be completed by comments using swagger-api annotations. + +This library supports: + +* OpenAPI 3 +* Spring-boot v3 (Java 17 & Jakarta EE 9) +* JSR-303, specifically for @NotNull, @Min, @Max, and @Size. +* Swagger-ui +* OAuth 2 +* GraalVM native images + +The following video introduces the Library: + + +[link=https://youtu.be/ondlnm5ZoFM?t=9,window=_blank] +image::img/spring-io-24.png[spring.io conference] + + +This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal). + diff --git a/src/docs/asciidoc/migrating-from-springdoc-v1.adoc b/src/docs/asciidoc/migrating-from-springdoc-v1.adoc new file mode 100644 index 0000000..aadf7f8 --- /dev/null +++ b/src/docs/asciidoc/migrating-from-springdoc-v1.adoc @@ -0,0 +1,57 @@ +[[migrating-from-springdoc-v1]] +== Migrating from springdoc-openapi v1 + +All the modules have been renamed. +`springdoc-openapi-starter-common` integrates many spring modules support in order to hide the maximum of complexity. +It allows the support out of the box for `Actuator` / `Spring Cloud Function` / `Spring Data Rest`/ `Spring Native`/ `Spring Hateoas` / `Spring Securtiy` / `Kotlin`/ `Javadoc`. + +The following table describes the main modules changes: + +|=== +|springdoc-openapi-v1 | springdoc-openapi-v2 | Description + +|`springdoc-openapi-common` |`springdoc-openapi-starter-common` | Includes foundation `springdoc-openapi` features +|`springdoc-openapi-data-rest` | `springdoc-openapi-starter-common` | For Spring Data Rest support +|`springdoc-openapi-groovy` | `springdoc-openapi-starter-common` | For Groovy support +|`springdoc-openapi-hateoas` | `springdoc-openapi-starter-common` | For Spring Hateoas support +|`springdoc-openapi-javadoc` | `springdoc-openapi-starter-common` | For Javadoc support +|`springdoc-openapi-kotlin`| `springdoc-openapi-starter-common` | For Kotlin support +|`springdoc-openapi-security` | `springdoc-openapi-starter-common` | For Spring Security support +|`springdoc-openapi-webmvc-core`| `springdoc-openapi-starter-webmvc-api` | For Spring WebMvc support +|`springdoc-openapi-webflux-core` | `springdoc-openapi-starter-webflux-api` | For Spring WebFlux support +|`springdoc-openapi-ui` | `springdoc-openapi-starter-webmvc-ui` | For using the Swagger-UI in a Spring WebMvc context +|`springdoc-openapi-webflux-ui` | `springdoc-openapi-starter-webflux-ui` | For using the Swagger-UI in a Spring WebFlux context +|=== + +IMPORTANT: classes/annotations changes + +|=== +|springdoc-openapi-v1 | springdoc-openapi-v2 + +|`org.springdoc.core.SpringDocUtils` | `org.springdoc.core.utils.SpringDocUtils` +|`org.springdoc.api.annotations.ParameterObject` | `org.springdoc.core.annotations.ParameterObject` +|`org.springdoc.core.GroupedOpenApi` | `org.springdoc.core.models.GroupedOpenApi` +|`org.springdoc.core.customizers.OpenApiCustomiser` | `org.springdoc.core.customizers.OpenApiCustomizer` +|`org.springdoc.core.Constants` | `org.springdoc.core.utils.Constants` +|`org.springdoc.core.SwaggerUiConfigParameters` | `org.springdoc.core.properties.SwaggerUiConfigParameters` +|=== + +TIP: Migration tips + +The following modules are not anymore needed and can be removed: + +- `springdoc-openapi-javadoc` +- `springdoc-openapi-kotlin` +- `springdoc-openapi-data-rest` +- `springdoc-openapi-security` +- `springdoc-openapi-webmvc-core` +- `springdoc-openapi-webflux-core` +- `springdoc-openapi-hateoas` +- `springdoc-openapi-groovy` + +In addition: + +* Replace `springdoc-openapi-ui` by `springdoc-openapi-starter-webmvc-ui` +* Replace `springdoc-openapi-webflux-ui` by `springdoc-openapi-starter-webflux-ui` + + diff --git a/src/docs/asciidoc/migrating-from-springfox.adoc b/src/docs/asciidoc/migrating-from-springfox.adoc new file mode 100644 index 0000000..4d74d2e --- /dev/null +++ b/src/docs/asciidoc/migrating-from-springfox.adoc @@ -0,0 +1,113 @@ +[[migrating-from-springfox]] +== Migrating from SpringFox + +* Remove springfox and swagger 2 dependencies. Add `springdoc-openapi-starter-webmvc-ui` dependency instead. + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-starter-webmvc-ui + {springdoc-version} + +---- + +* Replace swagger 2 annotations with swagger 3 annotations (it is already included with `springdoc-openapi-starter-webmvc-ui` dependency). +Package for swagger 3 annotations is `io.swagger.v3.oas.annotations`. + +- `@Api` -> `@Tag` +- `@ApiIgnore` -> `@Parameter(hidden = true)` or `@Operation(hidden = true)` or `@Hidden` +- `@ApiImplicitParam` -> `@Parameter` +- `@ApiImplicitParams` -> `@Parameters` +- `@ApiModel` -> `@Schema` +- `@ApiModelProperty(allowEmptyValue = true)` -> `@Schema(nullable = true)` +- `@ApiModelProperty` -> `@Schema` +- `@ApiOperation(value = "foo", notes = "bar")` -> `@Operation(summary = "foo", description = "bar")` +- `@ApiParam` -> `@Parameter` +- `@ApiResponse(code = 404, message = "foo")` -> `@ApiResponse(responseCode = "404", description = "foo")` + +* This step is optional: Only if you have **multiple** `Docket` beans replace them with `GroupedOpenApi` beans. + +Before: + +[source,java, subs="attributes+"] +---- + @Bean + public Docket publicApi() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public")) + .paths(PathSelectors.regex("/public.*")) + .build() + .groupName("springshop-public") + .apiInfo(apiInfo()); + } + + @Bean + public Docket adminApi() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin")) + .paths(PathSelectors.regex("/admin.*")) + .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class)) + .build() + .groupName("springshop-admin") + .apiInfo(apiInfo()); + } +---- + +Now: + +[source,java, subs="attributes+"] +---- + @Bean + public GroupedOpenApi publicApi() { + return GroupedOpenApi.builder() + .group("springshop-public") + .pathsToMatch("/public/**") + .build(); + } + @Bean + public GroupedOpenApi adminApi() { + return GroupedOpenApi.builder() + .group("springshop-admin") + .pathsToMatch("/admin/**") + .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class)) + .build(); + } +---- + +If you have **only one** `Docket` -- remove it and instead add properties to your `application.properties`: + +[source,properties, subs="attributes+"] +---- +springdoc.packagesToScan=package1, package2 +springdoc.pathsToMatch=/v1, /api/balance/** +---- + +* Add bean of `OpenAPI` type. See example: + +[source,java, subs="attributes+"] +---- + @Bean + public OpenAPI springShopOpenAPI() { + return new OpenAPI() + .info(new Info().title("SpringShop API") + .description("Spring shop sample application") + .version("v0.0.1") + .license(new License().name("Apache 2.0").url("http://springdoc.org"))) + .externalDocs(new ExternalDocumentation() + .description("SpringShop Wiki Documentation") + .url("https://springshop.wiki.github.org/docs")); + } +---- + +* If the swagger-ui is served behind a proxy: + ** link:index.html#how-can-i-deploy-springdoc-openapi-starter-webmvc-ui-behind-a-reverse-proxy[how-can-i-deploy-springdoc-openapi-starter-webmvc-ui-behind-a-reverse-proxy] +* To customise the Swagger UI + ** link:index.html#how-can-i-configure-swagger-ui[how-can-i-configure-swagger-ui] +* To hide an operation or a controller from documentation + ** link:index.html#how-can-i-hide-an-operation-or-a-controller-from-documentation[how-can-i-hide-an-operation-or-a-controller-from-documentation] + + + diff --git a/src/docs/asciidoc/modules.adoc b/src/docs/asciidoc/modules.adoc new file mode 100644 index 0000000..295a55a --- /dev/null +++ b/src/docs/asciidoc/modules.adoc @@ -0,0 +1,308 @@ +[[modules]] +== Springdoc-openapi Modules + +=== General overview +image::img/common.png[Architecture] + +=== Spring WebMvc support + +* Documentation will be available at the following url for json format: `\http://server:port/context-path/v3/api-docs` +** server: The server name or IP +** port: The server port +** context-path: The context path of the application +* Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml +* Add the library to the list of your project dependencies. (No additional configuration is needed) + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-starter-webmvc-api + {springdoc-version} + +---- + +NOTE: This dependency is relevant if you want to generate the OpenAPI description without using the swagger-ui. + +TIP: For custom path of the OpenAPI documentation in Json format, add a custom springdoc property, in your spring-boot configuration file: + +[source,properties, subs="attributes+"] +---- +# /api-docs endpoint custom path +springdoc.api-docs.path=/api-docs +---- + + +=== Spring WebFlux support + +* Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml +* Add the library to the list of your project dependencies (No additional configuration is needed) + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-starter-webflux-api + {springdoc-version} + +---- + + +=== Spring Hateoas support +The support for Spring Hateoas is available using the dependency springdoc-openapi-hateoas. + +The projects that use `spring-boot-starter-hateoas` should use: + +- `springdoc-openapi-starter-webmvc-api` if they need only the access to the OpenAPI endpoints +- OR `springdoc-openapi-starter-webmvc-ui`, if they need also the access to the swagger-ui + + +=== Spring Data Rest support + +`springdoc-openapi` project supports `spring-boot-starter-data-rest` types like: `@RepositoryRestResource` and `QuerydslPredicate` annotations. + +The projects that use `spring-boot-starter-data-rest` should use: + +- `springdoc-openapi-starter-webmvc-api` if they need only the access to the OpenAPI endpoints +- OR `springdoc-openapi-starter-webmvc-ui`, if they need also the access to the swagger-ui + +=== Spring Security support + +`springdoc-openapi` helps ignoring @AuthenticationPrincipal type in case it is used on REST Controllers. + +`springdoc-openapi` supports also exposing Oauth2 endpoints of `spring-security-oauth2-authorization-server`. + +The projects that use `spring-boot-starter-security` or `spring-security-oauth2-authorization-server` should use: + +- `springdoc-openapi-starter-webmvc-api` if they depend on `spring-boot-starter-web` and they only need the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webmvc-ui`, if they depend on `spring-boot-starter-web` and they also need the access to the swagger-ui. +- OR `springdoc-openapi-starter-webflux-api` if they depend on `spring-boot-starter-webflux` and they only the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webflux-ui`, if they depend on `spring-boot-starter-webflux` and they also need the access to the swagger-ui. + +=== Actuator support + +* In order to display `spring-boot-actuator` endpoints, simply add the following property: + +[source,properties] +---- +springdoc.show-actuator=true +---- + +Starting from the release `1.5.1`, it will be possible to expose the **swagger-ui** and the **openapi** endpoints on **actuator port**. + +NOTE: The actuator management port has to be different from the application port. + +To expose the swagger-ui, on the management port, you should set + +[source,properties] +---- +springdoc.use-management-port=true +# This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path. +management.endpoints.web.exposure.include=openapi, swagger-ui +---- + +Once enabled, you should also be able to see the springdoc-openapi endpoints under: (host and port depends on your settings) +- `\http://serverName:managementPort/actuator` + +For example, if you have the following settings: + +Two endpoints will be available: + +. REST API that holdes the OpenAPI definition: + +- `\http://serverName:managementPort/actuator/openapi` + +. An Endpoint, that routes to the swagger-ui: + +- `\http://serverName:managementPort/actuator/swagger-ui` + +[source,properties] +---- +management.server.port=9090 +---- + +For the example, you should also be able to see the springdoc-openapi endpoints: + +- `\http://serverName:9090/actuator` +- `\http://serverName:9090/actuator/swagger-ui` +- `\http://serverName:9090/actuator/openapi` + +All the path `springdoc-openapi` properties are not applicable when `springdoc.use-management-port=true`. + +TIP: If you want to reach the application endpoints, from the swagger-ui deployed beneath the actuator base path, using a different port from your application, `CORS for your endpoints` on your application level should be enabled. + +Additionally, it is also possible to combine this property, with the existing property to display the actuator endpoints in the swagger-ui. + +[source,properties] +---- +springdoc.show-actuator=true +---- + +Once enabled: +- A dedicated group for the actuator endpoints will be by default added. +- If no group is defined for the application, a default one will be added. + +The swagger-ui will be then accessible through the actuator port: + +- `\http://serverName:managementPort/actuator/swagger-ui` + +If the management port is different from the application port and `springdoc.use-management-port` is not defined but `springdoc.show-actuator` is set to true: + +- The swagger-ui will be then accessible through the application port. For example: `\http://serverName:applicationPort/swagger-ui.html` +- A dedicated group for the actuator endpoints will be by default added. +- If no group is defined for the application, a default one will be added. + + +TIP: If you want to reach the actuator endpoints for this case (different port from your application), `CORS` for your actuator endpoints should be enabled. + +Note: The naming of these new endpoints beneath the actuator base path cannot be customized for now. + +=== Spring Cloud Function Web support + +`spring-cloud-function-web` exposes Java Function as REST endpoint automatically. +* Since version `v1.6.3`, the support of functional endpoints has been added. + +* These starters will display the OpenAPI description of the `spring-cloud-function-web` endpoints. +- If you are using `spring-web`, simply add the `springdoc-openapi-starter-webmvc-ui` dependency. +- If you are using `spring-webflux`, simply add the `springdoc-openapi-starter-webflux-ui` dependency. + + +The customisation of the output can be achieved programmatically through `OpenApiCustomizer` or with the annotations: `@RouterOperations` and `@RouterOperation`. +For annotation usage, you have: +* `@RouterOperation`: It can be used alone, if the customisation is related to a single REST API. +When using `@RouterOperation`, it's not mandatory to fill the path + +* `@RouterOperation`, contains the `@Operation` annotation. +The `@Operation` annotation can also be placed on the bean method level if the property beanMethod is declared. + +IMPORTANT: Don't forget to set **operationId** which is **mandatory**. + +[source,java] +---- +@Bean +@RouterOperation(operation = @Operation(description = "Say hello", operationId = "hello", tags = "persons", + responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = PersonDTO.class))))) +public Supplier helloSupplier() { + return () -> new PersonDTO(); +} +---- + +* `@RouterOperations`: This annotation should be used to describe the multiple REST APIs exposed by `spring-cloud-function-web`. +When using `RouterOperations`, it's mandatory to fill the method property. + +* A `@RouterOperations`, contains many `@RouterOperation`. + +[source,java] +---- +@Bean +@RouterOperations({ + @RouterOperation(method = RequestMethod.GET, operation = @Operation(description = "Say hello GET", operationId = "lowercaseGET", tags = "persons")), + @RouterOperation(method = RequestMethod.POST, operation = @Operation(description = "Say hello POST", operationId = "lowercasePOST", tags = "positions")) +}) +public Function, Flux> lowercase() { + return flux -> flux.map(value -> value.toLowerCase()); +} +---- + +Some code samples are available on GITHUB of demos: + +* link:https://github.com/springdoc/springdoc-openapi-demos/tree/master/demo-spring-cloud-function[Sample applications with Spring Cloud Function Web, window="_blank"] + + +=== Kotlin support + +`springdoc-openapi` supports Kotlin types. + +The projects that use `Kotlin` should use: + +- `springdoc-openapi-starter-webmvc-api` if they depend on `spring-boot-starter-web` and they only need the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webmvc-ui`, if they depend on `spring-boot-starter-web` and they also need the access to the swagger-ui. +- OR `springdoc-openapi-starter-webflux-api` if they depend on `spring-boot-starter-webflux` and they only the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webflux-ui`, if they depend on `spring-boot-starter-webflux` and they also need the access to the swagger-ui. + +NOTE: In addition, your project should add `jackson-module-kotlin` as well to have the full support of `Kotlin` types: +[source,xml, subs="attributes+"] +---- + + com.fasterxml.jackson.module + jackson-module-kotlin + +---- + +=== Groovy support + +The projects that use `Groovy` should use: + +- `springdoc-openapi-starter-webmvc-api` if they depend on `spring-boot-starter-web` and they only need the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webmvc-ui`, if they depend on `spring-boot-starter-web` and they also need the access to the swagger-ui. +- OR `springdoc-openapi-starter-webflux-api` if they depend on `spring-boot-starter-webflux` and they only the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webflux-ui`, if they depend on `spring-boot-starter-webflux` and they also need the access to the swagger-ui. + + +=== Javadoc support + +`springdoc-openapi` can introspect `Javadoc` annotations and comments: + +- The javadoc comment of a method: is resolved as the `@Operation` description +- ``@return ``: is resolved as the `@Operation` response description +- The javadoc comment of an attribute: is resolved as '@Schema' description for this field. + +The projects that needs `Javadoc` support should use: + +- `springdoc-openapi-starter-webmvc-api` if they depend on `spring-boot-starter-web` and they only need the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webmvc-ui`, if they depend on `spring-boot-starter-web` and they also need the access to the swagger-ui. +- OR `springdoc-openapi-starter-webflux-api` if they depend on `spring-boot-starter-webflux` and they only the access to the OpenAPI endpoints. +- OR `springdoc-openapi-starter-webflux-ui`, if they depend on `spring-boot-starter-webflux` and they also need the access to the swagger-ui. + +NOTE: In addition, your project should add https://github.com/dnault/therapi-runtime-javadoc[`therapi-runtime-javadoc`] to read Javadoc comments at runtime. +Ensure that you add it as well as its annotation processor to your project's dependencies. Otherwise, the Javadoc support will fail silently. + +[source,xml, subs="attributes+"] +---- + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + com.github.therapi + therapi-runtime-javadoc-scribe + 0.15.0 + + + + + + + + + + com.github.therapi + therapi-runtime-javadoc + 0.15.0 + +---- + +TIP: If both a swagger-annotation description and a javadoc comment are present. The value of the swagger-annotation description will be used. + +=== Springdoc-openapi BOM +Starting from version `v2.8.7`, `springdoc-openapi` provides a BOM (Bill of Materials) to manage the dependencies of the project. +You can declare it in your project as follows: + +[source,xml, subs="attributes+"] +---- + + + + org.springdoc + springdoc-openapi-bom + {springdoc-version} + pom + import + + + +---- \ No newline at end of file diff --git a/src/docs/asciidoc/other-resources.adoc b/src/docs/asciidoc/other-resources.adoc new file mode 100644 index 0000000..eca3349 --- /dev/null +++ b/src/docs/asciidoc/other-resources.adoc @@ -0,0 +1,27 @@ +[[other-resources]] +== Other resources + +=== Additional resources to get started +- link:https://github.com/springdoc/springdoc-openapi[View project on GitHub, window="_blank"] image:img/github-logo.png[link="https://github.com/springdoc/springdoc-openapi"] +- link:https://prezi.com/view/r4DP4TCmYUJk1eaqjKG4/[Springdoc-openapi presentation, window="_blank"] +- link:https://www.baeldung.com/spring-rest-openapi-documentation[Baeldung, window="_blank"] +- link:https://dzone.com/articles/openapi-3-documentation-with-spring-boot[DZone Part1, window="_blank"] +- link:https://dzone.com/articles/doing-more-with-springdoc-openapi[DZone Part2, window="_blank"] +- link:https://dzone.com/articles/extending-swagger-and-spring-doc-open-api[Extending Swagger and Spring Doc Open API, window="_blank"] +- link:https://piotrminkowski.com/2020/02/20/microservices-api-documentation-with-springdoc-openapi/[Piotrminkowski Blog, window="_blank"] + + +=== Dependencies repository + +The `springdoc-openapi` libraries are hosted on maven central repository. +The artifacts can be viewed accessed at the following locations: + +Releases: + +* link:https://central.sonatype.com/search?q=g:org.springdoc[https://central.sonatype.com/search?q=g:org.springdoc, window="_blank"] + +Snapshots: + +* link:https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/org/springdoc/[https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/org/springdoc/, window="_blank", window="_blank"] + + diff --git a/src/docs/asciidoc/plugins.adoc b/src/docs/asciidoc/plugins.adoc new file mode 100644 index 0000000..aabccf4 --- /dev/null +++ b/src/docs/asciidoc/plugins.adoc @@ -0,0 +1,81 @@ +[[plugins]] +== Springdoc-openapi Plugins + +=== Maven plugin + +The aim of `springdoc-openapi-maven-plugin` is to generate json and yaml OpenAPI description during build time. +The plugin works during integration-tests phase, and generate the OpenAPI description. +The plugin works in conjunction with spring-boot-maven plugin. + +You can test it during the integration tests phase using the maven command: + +[source,bash] +---- +mvn verify +---- + +In order to use this functionality, you need to add the plugin declaration on the plugins section of your pom.xml: + +[source,xml] +---- + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + -Dspring.application.admin.enabled=true + + + + + start + stop + + + + + + org.springdoc + springdoc-openapi-maven-plugin + 1.5 + + + integration-test + + generate + + + + +---- + +For more custom settings of the springdoc-openapi-maven-plugin, you can consult the plugin documentation: + +* link:https://github.com/springdoc/springdoc-openapi-maven-plugin[https://github.com/springdoc/springdoc-openapi-maven-plugin, window="_blank"] + +=== Gradle plugin + +This plugin allows you to generate an OpenAPI 3 specification for a Spring Boot application from a Gradle build. + +[source,groovy] +---- +plugins { + id("org.springframework.boot") version "3.1.2" + id("org.springdoc.openapi-gradle-plugin") version "1.9.0" +} +---- + +When you add this plugin and its runtime dependency plugins to your build file, the plugin creates the following tasks: + +* forkedSpringBootRun +* generateOpenApiDocs + +[source,bash] +---- +gradle clean generateOpenApiDocs +---- + +For more custom configuration of `springdoc-openapi-gradle-plugin` ,you can consult the plugin documentation: + +* link:https://github.com/springdoc/springdoc-openapi-gradle-plugin[https://github.com/springdoc/springdoc-openapi-gradle-plugin, window="_blank"] + diff --git a/src/docs/asciidoc/properties.adoc b/src/docs/asciidoc/properties.adoc new file mode 100644 index 0000000..b0948ba --- /dev/null +++ b/src/docs/asciidoc/properties.adoc @@ -0,0 +1,18 @@ +[[properties]] +== Springdoc-openapi Properties + +`springdoc-openapi` relies on standard link:https://docs.spring.io/spring-boot/reference/features/external-config.html[spring configuration properties, window="_blank"] (yml or properties) using the standard files locations. + + +=== springdoc-openapi core properties + +include::core-properties.adoc[] + +=== swagger-ui properties +- The support of the swagger-ui properties is available on `springdoc-openapi`. See link:https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/[Official documentation, window="_blank"]. + +- You can use the same swagger-ui properties in the documentation as Spring Boot properties. + +NOTE: All these properties should be declared with the following prefix: `springdoc.swagger-ui` + +include::ui-properties.adoc[] diff --git a/src/docs/asciidoc/sitemap.xml b/src/docs/asciidoc/sitemap.xml new file mode 100644 index 0000000..65b573e --- /dev/null +++ b/src/docs/asciidoc/sitemap.xml @@ -0,0 +1,123 @@ + + + + https://springdoc.org/ + 2023-06-30 + + + https://springdoc.org/index.html + 2023-06-30 + + + https://springdoc.org/core-properties.html + 2023-06-30 + + + https://springdoc.org/demos.html + 2023-06-30 + + + https://springdoc.org/faq.html + 2023-06-30 + + + https://springdoc.org/features.html + 2023-06-30 + + + https://springdoc.org/getting-started.html + 2023-06-30 + + + https://springdoc.org/intro.html + 2023-06-30 + + + https://springdoc.org/migrating-from-springfox.html + 2023-06-30 + + + https://springdoc.org/modules.html + 2023-06-30 + + + https://springdoc.org/other-resources.html + 2023-06-30 + + + https://springdoc.org/plugins.html + 2023-06-30 + + + https://springdoc.org/properties.html + 2023-06-30 + + + https://springdoc.org/ui-properties.html + 2023-06-30 + + + https://springdoc.org/thanks.html + 2023-06-30 + + + https://springdoc.org/v1 + 2023-06-30 + + + https://springdoc.org/v1/index.html + 2023-06-30 + + + https://springdoc.org/v1/core-properties.html + 2023-06-30 + + + https://springdoc.org/v1/demos.html + 2023-06-30 + + + https://springdoc.org/v1/faq.html + 2023-06-30 + + + https://springdoc.org/v1/features.html + 2023-06-30 + + + https://springdoc.org/v1/getting-started.html + 2023-06-30 + + + https://springdoc.org/v1/intro.html + 2023-06-30 + + + https://springdoc.org/v1/migrating-from-springfox.html + 2023-06-30 + + + https://springdoc.org/v1/modules.html + 2023-06-30 + + + https://springdoc.org/v1/other-resources.html + 2023-06-30 + + + https://springdoc.org/v1/plugins.html + 2023-06-30 + + + https://springdoc.org/v1/properties.html + 2023-06-30 + + + https://springdoc.org/v1/ui-properties.html + 2023-06-30 + + + https://springdoc.org/v1/thanks.html + 2023-06-30 + + \ No newline at end of file diff --git a/src/docs/asciidoc/sponsor.adoc b/src/docs/asciidoc/sponsor.adoc new file mode 100644 index 0000000..ed4bc53 --- /dev/null +++ b/src/docs/asciidoc/sponsor.adoc @@ -0,0 +1,53 @@ +[[sponsor]] +== Sponsor + +`springdoc-openapi` is on link:https://opencollective.com/springdoc[Open Collective, window="_blank"]. + +If you ❤️ this project consider becoming a link:https://github.com/sponsors/springdoc[sponsor, window="_blank"]. + +This money is used to cover project expenses and your donation will help the project live and grow successfully. + +Thank you to our bronze sponsors! +++++ +

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

+++++ + +=== Benefits of being a bronze sponsor +Bronze sponsors donate $50 per month to the project, and get the following benefits: + +- You will receive a Sponsor badge 🎖!. Visibility on the front page of https://springdoc.org in the `welcome` page (about 55,000 views/month on May, 2022). +- “Thank you” tweet from `springdoc team'. + +=== Benefits of being a silver sponsor +Silver sponsors donate $100 per month to the project, and get the following benefits: + +- Same benefits as bronze sponsors (visibility on main pages, and thank you tweet). +- The ability to get support for 2 `issues` every month, non transferable. +- If issues are not created by the end of the month, it is lost + +=== Benefits of being a gold sponsor +Gold sponsors donate $500 per month to the project, and get the following benefits: + +- Same benefits as silver sponsors (visibility on main pages, and thank you tweet). +- The ability to get support for 10 `issues` every month, non transferable. +- Company logos on all https://springdoc.org page footers +- If issues are not created by the end of the month, the remaining ones are lost. + + + diff --git a/src/docs/asciidoc/thanks.adoc b/src/docs/asciidoc/thanks.adoc new file mode 100644 index 0000000..2034eaf --- /dev/null +++ b/src/docs/asciidoc/thanks.adoc @@ -0,0 +1,9 @@ +[[thanks]] +== Special Thanks + +* Thank you to link:https://spring.io/team[The Spring Team , window="_blank"] for sharing all relevant resources around Spring projects. + +* Thanks a lot link:https://www.jetbrains.com/?from=springdoc-openapi[JetBrains, window="_blank"] for supporting springdoc-openapi project. + +image::https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg[JetBrains logo] + diff --git a/src/docs/asciidoc/ui-properties.adoc b/src/docs/asciidoc/ui-properties.adoc new file mode 100644 index 0000000..ecce440 --- /dev/null +++ b/src/docs/asciidoc/ui-properties.adoc @@ -0,0 +1,66 @@ +[[ui-properties]] + +|=== +|Parameter name | Default Value | Description + +|springdoc.swagger-ui.path | `/swagger-ui.html` |`String`, For custom path of the swagger-ui HTML documentation. +|springdoc.swagger-ui.enabled | `true` | `Boolean`. To disable the swagger-ui endpoint (/swagger-ui.html by default). +|springdoc.swagger-ui.configUrl | `/v3/api-docs/swagger-config` | `String`. URL to fetch external configuration document from. +|springdoc.swagger-ui.layout | `BaseLayout` | `String`. The name of a component available via the plugin system to use as the top-level layout for Swagger UI. +|springdoc.swagger-ui.validatorUrl | | By default, Swagger UI does not validate specs. You can use this parameter to set a validator URL, for example for against swagger.io’s online validator. +|springdoc.swagger-ui.tryItOutEnabled | `false` |`Boolean`. Controls whether the "Try it out" section should be enabled by default. +|springdoc.swagger-ui.filter | `false` | `Boolean OR String`. If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be Boolean to enable or disable, or a string, in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag. +|springdoc.swagger-ui.operationsSorter | | `Function=(a => a)`. Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged. +|springdoc.swagger-ui.tagsSorter | | `Function=(a => a)`. Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort[see Array.prototype.sort() , window="_blank"] to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger UI. +|springdoc.swagger-ui.oauth2RedirectUrl | `/swagger-ui/oauth2-redirect.html` | `String`. OAuth redirect URL. +|springdoc.swagger-ui.displayOperationId | `false` | `Boolean`. Controls the display of operationId in operations list. The default is `false`. +|springdoc.swagger-ui.displayRequestDuration | `false` | `Boolean`. Controls the display of the request duration (in milliseconds) for "Try it out" requests. +|springdoc.swagger-ui.deepLinking | `false` | `Boolean`. If set to `true`, enables deep linking for tags and operations. See the [Deep Linking documentation](https://swagger.io/docs/open-source-tools/swagger-ui/usage/deep-linking) for more information. +|springdoc.swagger-ui.defaultModelsExpandDepth | `1` | `Number`. The default expansion depth for models (set to -1 completely hide the models). +|springdoc.swagger-ui.defaultModelExpandDepth | `1` | `Number`. The default expansion depth for the model on the model-example section. +|springdoc.swagger-ui.defaultModelRendering | | `String=["example"*, "model"]`. Controls how the model is shown when the API is first rendered. (The user can always switch the rendering for a given model by clicking the 'Model' and 'Example Value' links.) +|springdoc.swagger-ui.docExpansion | | `String=["list"*, "full", "none"]`. Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). +|springdoc.swagger-ui.maxDisplayedTags | | `Number`. If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations. +|springdoc.swagger-ui.showExtensions | `false` | `Boolean`. Controls the display of vendor extension (`x-`) fields and values for Operations, Parameters, and Schema. +|springdoc.swagger-ui.url | | `String`.To configure, the path of a custom OpenAPI file . Will be ignored if `urls` is used. +|springdoc.swagger-ui.showCommonExtensions | `false` | `Boolean`. Controls the display of extensions (`pattern`, `maxLength`, `minLength`, `maximum`, `minimum`) fields and values for Parameters. +|springdoc.swagger-ui.supportedSubmitMethods | | `Array=[get, put, post, delete, options, head, patch, trace]`. List of HTTP methods that have the "Try it out" feature enabled. An empty array disables "Try it out" for all operations. This does not filter the operations from the display. +|springdoc.swagger-ui.queryConfigEnabled | `false` | `Boolean`. Disabled since `v1.6.0`. This parameter enables (legacy) overriding configuration parameters via URL search params. link:https://github.com/swagger-api/swagger-ui/security/advisories/GHSA-qrmm-w75w-3wpx[See security advisory , window="_blank"] before enabling this feature. +|springdoc.swagger-ui.oauth. additionalQueryStringParams | | `String`. Additional query parameters added to authorizationUrl and tokenUrl. +|springdoc.swagger-ui.disable-swagger-default-url | `false` | `Boolean`. To disable the swagger-ui default petstore url. (Available since v1.4.1). +|springdoc.swagger-ui.urls[0].url | | `URL`. The url of the swagger group, used by Topbar plugin. URLs must be unique among all items in this array, since they're used as identifiers. +|springdoc.swagger-ui.urls[0].name | | `String`. The name of the swagger group, used by Topbar plugin. Names must be unique among all items in this array, since they're used as identifiers. +|springdoc.swagger-ui.urlsPrimaryName | | `String`. The name of the swagger group which will be displayed when Swagger UI loads. +|springdoc.swagger-ui.oauth.clientId | | `String`. Default clientId. MUST be a string. +|springdoc.swagger-ui.oauth.clientSecret | | `String`. Default clientSecret. Never use this parameter in your production environment. It exposes crucial security information. This feature is intended for dev/test environments only. +|springdoc.swagger-ui.oauth.realm | | `String`. realm query parameter (for OAuth 1) added to authorizationUrl and tokenUrl. +|springdoc.swagger-ui.oauth.appName | | `String`. OAuth application name, displayed in authorization popup. +|springdoc.swagger-ui.oauth.scopeSeparator | | `String`. OAuth scope separator for passing scopes, encoded before calling, default value is a space (encoded value %20). +|springdoc.swagger-ui.csrf.enabled | `false` | `Boolean`. To enable CSRF support +|springdoc.swagger-ui.csrf.use-local-storage | `false` | `Boolean`. To get the CSRF token from the Local Storage. +|springdoc.swagger-ui.csrf.use-session-storage | `false` | `Boolean`. To get the CSRF token from the Session Storage. +|springdoc.swagger-ui.csrf.cookie-name | `XSRF-TOKEN` | `String`. Optional CSRF, to set the CSRF cookie name. +|springdoc.swagger-ui.csrf.header-name | `X-XSRF-TOKEN` | `String`. Optional CSRF, to set the CSRF header name. +|springdoc.swagger-ui.syntaxHighlight.activated | `true` | `Boolean`. Whether syntax highlighting should be activated or not. +|springdoc.swagger-ui.syntaxHighlight.theme | `agate` | `String`. `String=["agate"*, "arta", "monokai", "nord", "obsidian", "tomorrow-night"]`. link:https://highlightjs.org/static/demo/[Highlight.js, window="_blank"] syntax coloring theme to use. (Only these 6 styles are available.) +|springdoc.swagger-ui.oauth. useBasicAuthentication WithAccessCodeGrant | `false` | `Boolean`. Only activated for the accessCode flow. During the authorization_code request to the tokenUrl, pass the Client Password using the HTTP Basic Authentication scheme (Authorization header with Basic base64encode(client_id + client_secret)). +|springdoc.swagger-ui.oauth. usePkceWithAuthorization CodeGrant | `false` | `Boolean`.Only applies to authorizatonCode flows. Proof Key for Code Exchange brings enhanced security for OAuth public clients. +|springdoc.swagger-ui.persistAuthorization | `false` | `Boolean`. If set to true, it persists authorization data and it would not be lost on browser close/refresh +|springdoc.swagger-ui.use-root-path | `false` | `Boolean`. If set to true, the swagger-ui will be accessible from the application root path directly. + +|=== + +++++ + + + +++++ + diff --git a/src/docs/asciidoc/v1/_attributes.adoc b/src/docs/asciidoc/v1/_attributes.adoc new file mode 100644 index 0000000..bf10d4b --- /dev/null +++ b/src/docs/asciidoc/v1/_attributes.adoc @@ -0,0 +1,16 @@ +:doctype: book +:idprefix: +:idseparator: - +:toc: left +:toclevels: 4 +:tabsize: 4 +:numbered: +:sectanchors: +:sectnums: +:icons: font +:hide-uri-scheme: +:docinfo: shared,private + +:sc-ext: java +:project-full-name: springdoc-openapi +:all: {asterisk}{asterisk} diff --git a/src/docs/asciidoc/v1/core-properties.adoc b/src/docs/asciidoc/v1/core-properties.adoc new file mode 100644 index 0000000..19d8c0f --- /dev/null +++ b/src/docs/asciidoc/v1/core-properties.adoc @@ -0,0 +1,56 @@ +[[core-properties]] + +|=== +|Parameter name | Default Value | Description + +|springdoc.api-docs.path | `/v3/api-docs` | `String`, For custom path of the OpenAPI documentation in Json format. +|springdoc.api-docs.enabled | `true` | `Boolean`. To disable the springdoc-openapi endpoint (/v3/api-docs by default). +|springdoc.packages-to-scan | `*`| `List of Strings`.The list of packages to scan (comma separated) +|springdoc.paths-to-match | `/*`| `List of Strings`.The list of paths to match (comma separated) +|springdoc.produces-to-match | `/*`| `List of Strings`.The list of produces mediaTypes to match (comma separated) +|springdoc.headers-to-match | `/*`| `List of Strings`.The list of headers to match (comma separated) +|springdoc.consumes-to-match | `/*`| `List of Strings`.The list of consumes mediaTypes to match (comma separated) +|springdoc.paths-to-exclude | | `List of Strings`.The list of paths to exclude (comma separated) +|springdoc.packages-to-exclude | | `List of Strings`.The list of packages to exclude (comma separated) +|springdoc.default-consumes-media-type | `application/json` | `String`. The default consumes media type. +|springdoc.default-produces-media-type | `*/*` | `String`.The default produces media type. +|springdoc.cache.disabled | `false` | `Boolean`. To disable the springdoc-openapi cache of the calculated OpenAPI. +|springdoc.show-actuator | `false` | `Boolean`. To display the actuator endpoints. +|springdoc.auto-tag-classes | `true` | `Boolean`. To disable the springdoc-openapi automatic tags. +|springdoc.model-and-view-allowed | `false` | `Boolean`. To allow RestControllers with ModelAndView return to appear in the OpenAPI description. +|springdoc.override-with-generic-response | `true` | `Boolean`. When true, automatically adds @ControllerAdvice responses to all the generated responses. +|springdoc.group-configs[0].group | | `String`.The group name +|springdoc.group-configs[0].display-name | | `String`.The display name of the group. +|springdoc.group-configs[0].packages-to-scan | `*`| `List of Strings`.The list of packages to scan for a group (comma separated) +|springdoc.group-configs[0].paths-to-match | `/*`| `List of Strings`.The list of paths to match for a group(comma separated) +|springdoc.group-configs[0].paths-to-exclude | ``| `List of Strings`.The list of paths to exclude for a group(comma separated) +|springdoc.group-configs[0].packages-to-exclude | | `List of Strings`.The list of packages to exclude for a group(comma separated) +|springdoc.group-configs[0].produces-to-match | `/*`| `List of Strings`.The list of produces mediaTypes to match (comma separated) +|springdoc.group-configs[0].consumes-to-match | `/*`| `List of Strings`.The list of consumes mediaTypes to match (comma separated) +|springdoc.group-configs[0].headers-to-match | `/*`| `List of Strings`.The list of headers to match (comma separated) +|springdoc.webjars.prefix | `/webjars` |`String`, To change the webjars prefix that is visible the URL of swagger-ui for spring-webflux. +|springdoc.api-docs.resolve-schema-properties | `false` | `Boolean`. To enable property resolver on @Schema (name, title and description). +|springdoc.remove-broken-reference-definitions | `true` | `Boolean`. To disable removal of broken reference definitions. +|springdoc.writer-with-default-pretty-printer | `false` | `Boolean`. To enable pretty print of the OpenApi specification. +|springdoc.model-converters.deprecating-converter.enabled | `true` | `Boolean`. To disable deprecating model converter. +|springdoc.model-converters.polymorphic-converter.enabled | `true` | `Boolean`. To disable polymorphic model converter. +|springdoc.model-converters.pageable-converter.enabled | `true` | `Boolean`. To disable pageable model converter. +|springdoc.model-converters.sort-converter.enabled | `true` | `Boolean`. To disable Sort converter. +|springdoc.use-fqn | `false` | `Boolean`. To enable fully qualified names. +|springdoc.show-login-endpoint | `false` | `Boolean`. To make spring security login-endpoint visible. +|springdoc.pre-loading-enabled | `false` | `Boolean`. Pre-loading setting to load OpenAPI on application startup. +|springdoc.pre-loading-locales | | `List of Strings`.The list of locales to load OpenAPI on application startup.(comma separated) If not specified, it will preload with the default Locale. +|springdoc.writer-with-order-by-keys | `false` | `Boolean`. Enable a deterministic/alphabetical ordering. +|springdoc.use-management-port | `false` | `Boolean`. To expose the swagger-ui on the actuator management port. +|springdoc.disable-i18n | `false` | `Boolean`. To disable automatic translation using i18n. +|springdoc.show-spring-cloud-functions | `true` | `Boolean`. To display the spring-cloud-function web endpoints. +|springdoc.api-docs.version | `openapi_3_0` | `String`. To Choose `OpenAPI 3.0` or `OpenAPI 3.1` (using the value `OPENAPI_3_1`). +|springdoc.default-flat-param-object | `false` | `Boolean`. To default flatten parameter. +|springdoc.default-support-form-data | `false` | `Boolean`. To default set parameters to form data when specifying api to accept form data. +|springdoc.nullable-request-parameter-enabled | `true` | `Boolean`. To default Enable Support for nullable request parameters in Kotlin. +|springdoc.show-oauth2-endpoints | `false` | `Boolean`. To make spring security oauth2-endpoint visible. +|springdoc.api-docs.resolve-extensions-properties | `false` | `Boolean`. To enable support of spring property resolver for `@ExtensionProperty`. +|springdoc.enable-default-api-docs | `true` | `Boolean`. To enable default OpenAPI endpoint `/v3/api-docs`. +|springdoc.trim-kotlin-indent | `false` | `Boolean`. Adjust indentation when parsing the `@Operation` annotation in Kotlin. +|=== + diff --git a/src/docs/asciidoc/v1/demos.adoc b/src/docs/asciidoc/v1/demos.adoc new file mode 100644 index 0000000..d3f69e3 --- /dev/null +++ b/src/docs/asciidoc/v1/demos.adoc @@ -0,0 +1,18 @@ +[[demos]] +== Springdoc-openapi Demos + +=== springdoc applications demos +* link:https://demos1.springdoc.org/demo-spring-boot-2-webmvc[Demo Spring Boot 2 Web MVC with OpenAPI 3, window="_blank"] +* link:https://demos1.springdoc.org/demo-spring-boot-2-webflux/swagger-ui.html[Demo Spring Boot 2 WebFlux with OpenAPI 3, window="_blank"] +* link:https://demos1.springdoc.org/demo-spring-boot-1-webmvc[Demo Spring Boot 1 Web MVC with OpenAPI 3, window="_blank"] +* link:https://demos1.springdoc.org/demo-spring-boot-2-webflux-functional/swagger-ui.html[Demo Spring Boot 2 WebFlux with Functional endpoints OpenAPI 3, window="_blank"] +* link:https://demos1.springdoc.org/demo-spring-hateoas[Demo Spring Boot 2 and Spring Hateoas with OpenAPI 3, window="_blank"] +* link:https://demos1.springdoc.org/demo-microservices/swagger-ui.html[Demo Spring Boot 2 and Spring Cloud Gateway, window="_blank"] +* link:https://demos1.springdoc.org/spring-cloud-function-webmvc[Demo Spring Boot 2 and Spring Cloud Function Web MVC, window="_blank"] +* link:https://demos1.springdoc.org/spring-cloud-function-webflux/swagger-ui.html[Demo Spring Boot 2 and Spring Cloud Function WebFlux, window="_blank"] + +image::img/pets.png[pets.png] + +=== Source code of the Demo Applications +* link:https://github.com/springdoc/springdoc-openapi-demos.git[https://github.com/springdoc/springdoc-openapi-demos.git, window="_blank"] + diff --git a/src/docs/asciidoc/v1/docinfo-footer.html b/src/docs/asciidoc/v1/docinfo-footer.html new file mode 100644 index 0000000..e69de29 diff --git a/src/docs/asciidoc/v1/docinfo.html b/src/docs/asciidoc/v1/docinfo.html new file mode 100644 index 0000000..19e2462 --- /dev/null +++ b/src/docs/asciidoc/v1/docinfo.html @@ -0,0 +1,5 @@ + diff --git a/src/docs/asciidoc/v1/faq.adoc b/src/docs/asciidoc/v1/faq.adoc new file mode 100644 index 0000000..04630f2 --- /dev/null +++ b/src/docs/asciidoc/v1/faq.adoc @@ -0,0 +1,1034 @@ +[[faq]] +== F.A.Q + +=== How can I define multiple OpenAPI definitions in one Spring Boot project? +You can define your own groups of API based on the combination of: API paths and packages to scan. Each group should have a unique `groupName`. +The OpenAPI description of this group, will be available by default on: + +* `\http://server:port/context-path/v3/api-docs/groupName` + +To enable the support of multiple OpenAPI definitions, a bean of type `GroupedOpenApi` needs to be defined. + +For the following Group definition(based on package path), the OpenAPI description URL will be : /v3/api-docs/**stores** + +[source,java] +---- +@Bean +public GroupedOpenApi storeOpenApi() { + String paths[] = {"/store/**"}; + return GroupedOpenApi.builder().group("stores").pathsToMatch(paths) + .build(); +} +---- + +For the following Group definition (based on package name), the OpenAPI description URL will be: /v3/api-docs/**users** + +[source,java] +---- +@Bean +public GroupedOpenApi userOpenApi() { + String packagesToscan[] = {"test.org.springdoc.api.app68.api.user"}; + return GroupedOpenApi.builder().group("users").packagesToScan(packagesToscan) + .build(); +} +---- + +For the following Group definition(based on path), the OpenAPI description URL will be: /v3/api-docs/**pets** + +[source,java] +---- +@Bean +public GroupedOpenApi petOpenApi() { + String paths[] = {"/pet/**"}; + return GroupedOpenApi.builder().group("pets").pathsToMatch(paths) + .build(); +} +---- + +For the following Group definition (based on package name and path), the OpenAPI description URL will be: /v3/api-docs/**groups** + +[source,java] +---- +@Bean +public GroupedOpenApi groupOpenApi() { + String paths[] = {"/v1/**"}; + String packagesToscan[] = {"test.org.springdoc.api.app68.api.user", "test.org.springdoc.api.app68.api.store"}; + return GroupedOpenApi.builder().group("groups").pathsToMatch(paths).packagesToScan(packagesToscan) + .build(); +} +---- + +For more details about the usage, you can have a look at the following sample Test: + +* link:https://github.com/springdoc/springdoc-openapi/tree/master/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app68[https://github.com/springdoc/springdoc-openapi/tree/master/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app68, window="_blank"] + +=== How can I configure Swagger UI? +* The support of the swagger official properties is available on `springdoc-openapi`. See link:https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/[Official documentation, window="_blank"]. + +* You can use the same swagger properties in the documentation as Spring Boot properties. + +NOTE: All these properties should be declared with the following prefix: `springdoc.swagger-ui` + +=== How can I filter the resources documented in the output specification by the provided group? +* You can use the standard `swagger-ui` property filter. +[source,properties] +---- +springdoc.swagger-ui.filter=group-a +---- + +=== How can I disable/enable Swagger UI generation based on env variable? +* This property helps you disable only the UI. +[source,properties] +---- +springdoc.swagger-ui.enabled=false +---- +=== How can I control the default expansion setting for the operations and tags, in the Swagger UI, +* You can set this property in your application.yml like so for example: +[source,properties] +---- +springdoc.swagger-ui.doc-expansion= none +---- + +=== How can I change the layout of the `swagger-ui`? +* For layout options, you can use swagger-ui configuration options. For example: +[source,properties] +---- +springdoc.swagger-ui.layout=BaseLayout +---- + +=== How can I sort endpoints alphabetically? +* You can use the following `springdoc-openapi` properties: +[source,properties] +---- +#For sorting endpoints alphabetically +springdoc.swagger-ui.operationsSorter=alpha +#For sorting tags alphabetically +springdoc.swagger-ui.tagsSorter=alpha +---- + +=== How can I disable the try it out button? +* You have to set the following property: +[source,properties] +---- +springdoc.swagger-ui.supportedSubmitMethods=get, put, post, delete, options, head, patch, trace +---- + +=== How can I add Reusable Enums? +* You should add `@Schema(enumAsRef = true)` on your enum. + +=== How can i apply `enumAsRef = true` to all enums? +* Declare the following property: +[source,java] +---- +static { + io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true; +} +---- + +=== How can I explicitly set which paths to filter? +* You can set list of paths to include using the following property: +[source,properties] +---- +springdoc.pathsToMatch=/v1, /api/balance/** +---- + +=== How can I explicitly set which packages to scan? +* You can set list of packages to include using the following property: +[source,properties] +---- +springdoc.packagesToScan=package1, package2 +---- + +=== How can I set Swagger properties programmatically? + +These can be set by creating a `swaggerUiConfig` bean as follows: +[source,kotlin] +---- +@Bean +@Primary +fun swaggerUiConfig(config: SwaggerUiConfigProperties): SwaggerUiConfigProperties { + config.showCommonExtensions = true + config.queryConfigEnabled = true + return config +} +---- + +=== How can I ignore some field of model? +* You can use the following annotation on the top of the field that you want to hide: +* `@Schema(hidden = true)` + +=== How can I ignore `@AuthenticationPrincipal` parameter from spring-security? +* A solution workaround would be to use: `@Parameter(hidden = true)` +* For a project that uses `spring-security`, you should add the following dependency, in combination with the `springdoc-openapi-ui` dependency: + +[source,xml] +---- + + org.springdoc + springdoc-openapi-security + last.version + +---- + +=== Is there a Gradle plugin available? +* Yes. More details are available, in the link:https://springdoc.org/#gradle-plugin[gradle plugin] section. + +=== How can I hide a parameter from the documentation? +* You can use `@Parameter(hidden = true)` + +=== Is `@Parameters` annotation supported? +* Yes + +=== Does `springdoc-openapi` support Jersey? +* If you are using JAX-RS and as implementation Jersey (`@Path` for example), we do not support it. +* We only support exposing Rest Endpoints using Spring managed beans (`@RestController` for example). +* You can have a look at swagger-jaxrs2 project: +** link:https://github.com/swagger-api/swagger-samples/tree/2.0/java/java-jersey2-minimal[https://github.com/swagger-api/swagger-samples/tree/2.0/java/java-jersey2-minimal, window="_blank"] + +=== Can `springdoc-openapi` generate API only for `@RestController`? +* `@RestController` is equivalent to `@Controller` + `@RequestMapping` on the type level. +* For some legacy apps, we are constrained to still support both. +* If you need to hide the `@Controller` on the type level, in this case, you can use: `@Hidden` on controller level. +* Please note this annotation can be also used to hide some methods from the generated documentation. + +=== Are the following validation annotations supported : `@NotEmpty` `@NotBlank` `@PositiveOrZero` `@NegativeOrZero`? +* Yes + +=== How can I map `Pageable` (spring-data-commons) object to correct URL-Parameter in Swagger UI? + +The support for Pageable of spring-data-commons is available out-of-the box since `springdoc-openapi v1.6.0`. +For this, you have to combine `@ParameterObject` annotation with the `Pageable` type. + + +Before `springdoc-openapi v1.6.0`: + +* You can use as well `@ParameterObject` instead of `@PageableAsQueryParam` for HTTP `GET` methods. + +[source,java] +---- +static { + getConfig().replaceParameterObjectWithClass(org.springframework.data.domain.Pageable.class, Pageable.class) + .replaceParameterObjectWithClass(org.springframework.data.domain.PageRequest.class, Pageable.class); +} +---- + +* Another solution, is to configure Pageable manually: + - you will have to declare the explicit mapping of Pageable fields as Query Params and add the `@Parameter(hidden = true) Pageable pageable` on your pageable parameter. + - You should also, declare the annotation `@PageableAsQueryParam` provided by `springdoc-openapi` on the method level, or declare your own if need to define your custom description, defaultValue, ... + +If you want to disable the support of spring Pageable Type, you can use: +[source,properties] +---- +springdoc.model-converters.pageable-converter.enabled=false +---- + +NOTE: The property `springdoc.model-converters.pageable-converter.enabled` is only available since v1.5.11+ + +=== How can I generate enums in the generated description? +* You could add a property `allowableValues`, to `@Parameter`. For example: + +[source,java] +---- +@GetMapping("/example") +public Object example(@Parameter(name = "json", schema = @Schema(description = "var 1", type = "string", allowableValues = {"1", "2"})) +String json) { + return null; +} +---- + +* or you could override `toString` on your enum: + +[source,java] +---- +@Override +@JsonValue +public String toString() { + return String.valueOf(action); +} +---- + +=== How can I deploy `springdoc-openapi-ui` behind a reverse proxy? +* If your application is running behind a proxy, a load-balancer or in the cloud, the request information (like the host, port, scheme…​) might change along the way. Your application may be running on `10.10.10.10:8080`, but HTTP clients should only see `example.org`. + +* link:https://tools.ietf.org/html/rfc7239[RFC7239 "Forwarded Headers", window="_blank"] defines the Forwarded HTTP header; proxies can use this header to provide information about the original request. You can configure your application to read those headers and automatically use that information when creating links and sending them to clients in HTTP 302 responses, JSON documents or HTML pages. There are also non-standard headers, like `X-Forwarded-Host`, `X-Forwarded-Port`, `X-Forwarded-Proto`, `X-Forwarded-Ssl`, and `X-Forwarded-Prefix`. + +* If the proxy adds the commonly used `X-Forwarded-For` and `X-Forwarded-Proto headers`, setting server.forward-headers-strategy to NATIVE is enough to support those. With this option, the Web servers themselves natively support this feature; you can check their specific documentation to learn about specific behavior. + +* You need to make sure the following header is set in your reverse proxy configuration: `X-Forwarded-Prefix` +* For example, using Apache 2, configuration: +[source,properties] +---- +RequestHeader set X-Forwarded-Prefix "/custom-path" +---- +* Then, in your Spring Boot application make sure your application handles this header: `X-Forwarded-For`. There are two ways to achieve this: +[source,properties] +---- +server.use-forward-headers=true +---- +* If this is not enough, Spring Framework provides a `ForwardedHeaderFilter`. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK. +* Since Spring Boot 2.2, this is the new property to handle reverse proxy headers: + +[source,properties] +---- +server.forward-headers-strategy=framework +---- + +* And you can add the following bean to your application: + +[source,java] +---- +@Bean +ForwardedHeaderFilter forwardedHeaderFilter() { + return new ForwardedHeaderFilter(); +} +---- + +=== Is `@JsonView` annotations in Spring MVC APIs supported? +* Yes + +=== Adding `springdoc-openapi-ui` dependency breaks my `public/index.html` welcome page +* If you already have static content on your root, and you don't want it to be overridden by `springdoc-openapi-ui` configuration, you can just define a custom configuration of the `swagger-ui`, in order not to override the configuration of your files from in your context-root: +* For example use: +[source,properties] +---- +springdoc.swagger-ui.path= /swagger-ui/api-docs.html +---- + +=== How can I test the Swagger UI? +* You can have a look on this sample test of the UI: +** link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app1/SpringDocApp1Test.java[https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app1/SpringDocApp1Test.java, window="_blank"] + +=== How can I customise the OpenAPI object? +* You can write your own implementation of `OpenApiCustomizer`. +* An example is available on: +** link:https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app39/SpringDocTestApp.java[https://github.com/springdoc/springdoc-openapi/blob/main/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app39/SpringDocTestApp.java, window="_blank"] + +[source,java] +---- +@Bean +public OpenApiCustomizer customerGlobalHeaderOpenApiCustomizer() { + return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream()) + .forEach(operation -> operation.addParametersItem(new HeaderParameter().$ref("#/components/parameters/myGlobalHeader"))); +} +---- + +NOTE: This bean `OpenApiCustomizer` will be applied to the Default OpenAPI only. + +If you need the `OpenApiCustomizer` to applied to `GroupedOpenApi` as well, then use `GlobalOpenApiCustomizer` instead. + +=== How can I return an empty content as response? +* It is be possible to handle as return an empty content as response using, one of the following syntaxes: +* `content = @Content` +* `content = @Content(schema = @Schema(hidden = true))` +* For example: + +[source,java] +---- +@Operation(summary = "Get thing", responses = { + @ApiResponse(description = "Successful Operation", responseCode = "200", content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content), + @ApiResponse(responseCode = "401", description = "Authentication Failure", content = @Content(schema = @Schema(hidden = true))) }) +@RequestMapping(path = "/testme", method = RequestMethod.GET) +ResponseEntity testme() { + return ResponseEntity.ok("Hello"); +} +---- + +=== How are endpoints with multiple consuming media types supported? +* An overloaded method on the same class, with the same HTTP Method and path, will have as a result, only one OpenAPI Operation generated. +* In addition, it's recommended to have the `@Operation` in the level of one of the overloaded methods. Otherwise it might be overridden if it's declared many times within the same overloaded method. + +=== How can I get yaml and json (OpenAPI) in compile time? +* You can use `springdoc-openapi-maven-plugin` for this functionality: +** link:https://github.com/springdoc/springdoc-openapi-maven-plugin.git[https://github.com/springdoc/springdoc-openapi-maven-plugin.git, window="_blank"] +* You can customise the output directory (property outputDir): The default value is: ${project.build.directory} + +=== What are the ignored types in the documentation? +* `Principal`, `Locale`, `HttpServletRequest` and `HttpServletResponse` and other injectable parameters supported by Spring MVC are excluded. +* Full documentation here: +** link:https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments[https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments, window="_blank"] + +=== How can i disable ignored types: + +If you don't want to ignore the types `Principal`, `Locale`, `HttpServletRequest`, and others,: + +[source,java] +---- +SpringDocUtils.getConfig().removeRequestWrapperToIgnore(HttpServletRequest.class) +---- + + +=== How do I add authorization header in requests? +* You should add the `@SecurityRequirement` tags to your protected APIs. +* For example: +---- +@Operation(security = { @SecurityRequirement(name = "bearer-key") }) +---- +* And the security definition sample: + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI() { + return new OpenAPI() + .components(new Components() + .addSecuritySchemes("bearer-key", + new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT"))); +} +---- + +=== Differentiation to Springfox project + +* OAS 3 was released in July 2017, and there was no release of `springfox` to support OAS 3. +`springfox` covers for the moment only swagger 2 integration with Spring Boot. The latest release date is June 2018. So, in terms of maintenance there is a big lack of support lately. + +* We decided to move forward and share the library that we already used on our internal projects, with the community. +* The biggest difference with `springfox`, is that we integrate new features not covered by `springfox`: + +* The integration between Spring Boot and OpenAPI 3 standard. +* We rely on on `swagger-annotations` and `swagger-ui` only official libraries. +* We support new features on Spring 5, like `spring-webflux` with annotated and functional style. +* We do our best to answer all the questions and address all issues or enhancement requests + +=== How do I migrate to OpenAPI 3 with springdoc-openapi +* There is no relation between `springdoc-openapi` and `springfox`.If you want to migrate to OpenAPI 3: +* Remove all the dependencies and the related code to springfox +* Add `springdoc-openapi-ui` dependency +* If you don't want to serve the UI from your root path or there is a conflict with an existing configuration, you can just change the following property: +[source,properties] +---- +springdoc.swagger-ui.path=/you-path/swagger-ui.html +---- + +=== How can I set a global header? +* You may have global parameters with Standard OpenAPI description. +* If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi, you can use OpenAPI Bean. +* You can define common parameters under parameters in the global components section and reference them elsewhere via `$ref`. You can also define global header parameters. +* For this, you can override to OpenAPI Bean, and set the global headers or parameters definition on the components level. + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) { + return new OpenAPI() + .components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")) + .addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema()))) + .info(new Info() + .title("Petstore API") + .version(appVersion) + .description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.") + .termsOfService("http://swagger.io/terms/") + .license(new License().name("Apache 2.0").url("http://springdoc.org"))); +} +---- + +=== Are Callbacks supported? +* Yes + +=== How can I define SecurityScheme? +* You can use: `@SecurityScheme` annotation. +* Or you can define it programmatically, by overriding OpenAPI Bean: + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) { + return new OpenAPI() + .components(new Components().addSecuritySchemes("basicScheme", + new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))) + .info(new Info().title("SpringShop API").version(appVersion) + .license(new License().name("Apache 2.0").url("http://springdoc.org"))); +} +---- + +=== How can I hide an operation or a controller from documentation? +* You can use `@io.swagger.v3.oas.annotations.Hidden` annotation at `@RestController`, `@RestControllerAdvice` and method level +* The `@Hidden` annotation on exception handler methods, is considered when building generic (error) responses from `@ControllerAdvice` exception handlers. +* Or use: `@Operation(hidden = true)` + +=== How to configure global security schemes? +* For global SecurityScheme, you can add it inside your own OpenAPI definition: + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI() { + return new OpenAPI().components(new Components() + .addSecuritySchemes("basicScheme", new SecurityScheme() + .type(SecurityScheme.Type.HTTP).scheme("basic"))).info(new Info().title("Custom API") + .version("100")).addTagsItem(new Tag().name("mytag")); +} +---- + +=== Can I use spring property with swagger annotations? +* The support of spring property resolver for `@Info`: `title` * `description` * `version` * `termsOfService` +* The support of spring property resolver for `@Info.license`: `name` * `url` +* The support of spring property resolver for `@Info.contact`: `name` * `email` * `url` +* The support of spring property resolver for `@Operation`: `description` * `summary` +* The support of spring property resolver for `@Parameter`: `description` * `name` +* The support of spring property resolver for `@ApiResponse`: `description` +* Its also possible to declare security URLs for `@OAuthFlow`: `openIdConnectUrl` * `authorizationUrl` * `refreshUrl` * `tokenUrl` +* The support of spring property resolver for `@Schema`: `name` * `title` * `description` , by setting `springdoc.api-docs.resolve-schema-properties` to `true` + +=== How is server URL generated? +* Generating automatically server URL may be useful, if the documentation is not present. +* If the server annotations are present, they will be used instead. + +=== How can I disable springdoc-openapi cache? +* By default, the OpenAPI description is calculated once, and then cached. +* Sometimes the same swagger-ui is served behind internal and external proxies. some users want the server URL, to be computed on each http request. +* In order to disable springdoc cache, you will have to set the following property: +[source,properties] +---- +springdoc.cache.disabled= true +---- + +=== How can I expose the mvc api-docs endpoints without using the `swagger-ui`? +* You should use the `springdoc-openapi-core` dependency only: + +[source,xml] +---- + + org.springdoc + springdoc-openapi-webmvc-core + latest.version + +---- +=== How can I disable `springdoc-openapi` endpoints? +* Use the following property: +---- +springdoc.api-docs.enabled=false +---- + +=== How can I hide Schema of the the response? + +* To hide the response element, using `@Schema` annotation, as follows, at operation level: + +---- +@Operation(responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true)))) +---- + +* Or directly at `@ApiResponses` level: + +---- +@ApiResponses(value = {@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))) }) +OR +@ApiResponse(responseCode = "404", description = "Not found", content = @Content) +---- + +=== What is the URL of the `swagger-ui`, when I set a different context-path? + +* If you use different context-path: +[source,properties] +---- +server.servlet.context-path= /foo +---- +* The `swagger-ui` will be available on the following URL: +** `\http://server:port/foo/swagger-ui.html` + +=== Can I customize OpenAPI object programmatically? + +* You can Define your own OpenAPI Bean: If you need the definitions to appear globally (within every group), no matter if the group fulfills the conditions specified on the GroupedOpenApi, you can use OpenAPI Bean. + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI(@Value("${springdoc.version}") String appVersion) { + return new OpenAPI() + .components(new Components().addSecuritySchemes("basicScheme", + new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))) + .info(new Info().title("SpringShop API").version(appVersion) + .license(new License().name("Apache 2.0").url("http://springdoc.org"))); +} +---- +* If you need the definitions to appear within a specific group, and respect the conditions specified on the GroupedOpenApi, you can add OpenApiCustomiser to your GroupedOpenApi definition. + +[source,java] +---- +GroupedOpenApi.builder().group("users").pathsToMatch(paths).packagesToScan(packagedToMatch).addOpenApiCustomiser(customerGlobalHeaderOpenApiCustomiser()) + .build() + +@Bean +public OpenApiCustomiser customerGlobalHeaderOpenApiCustomiser() { + return openApi -> openApi.path("/foo", + new PathItem().get(new Operation().operationId("foo").responses(new ApiResponses() + .addApiResponse("default", new ApiResponse().description("") + .content(new Content().addMediaType("fatz", new MediaType())))))); +} +---- + + +=== Where can I find the source code of the demo applications? +* The source code of the application is available at the following GitHub repository: +** link:https://github.com/springdoc/springdoc-openapi-demos.git[https://github.com/springdoc/springdoc-openapi-demos.git, window="_blank"] + +=== Does this library supports annotations from interfaces? +* Yes + +=== What is the list of the excluded parameter types? +* link:https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments[https://docs.spring.io/spring/docs/5.1.x/spring-framework-reference/web.html#mvc-ann-arguments, window="_blank"]. + +=== Is file upload supported? +* The library supports the main file types: `MultipartFile`, `@RequestPart`, `FilePart` + +=== Can I use `@Parameter` inside `@Operation` annotation? +* Yes, it's supported + +=== Why my parameter is marked as required? +* Any `@GetMapping` parameters is marked as required, even if `@RequestParam` is missing. +* You can add `@Parameter(required=false)` annotation if you need different behaviour. +* Query parameters with `defaultValue` specified are marked as required. + +=== How are overloaded methods with the same endpoints, but with different parameters +* `springdoc-openapi` renders these methods as a single endpoint. It detects the overloaded endpoints, and generates parameters.schema.oneOf. + +=== What is a proper way to set up Swagger UI to use provided spec.yml? +* With this property, all the `springdoc-openapi` auto-configuration beans are disabled: +[source,properties] +---- +springdoc.api-docs.enabled=false +---- +* Then enable the minimal Beans configuration, by adding this Bean: + +[source,java] +---- +@Bean +SpringDocConfiguration springDocConfiguration(){ + return new SpringDocConfiguration(); +} + +@Bean +SpringDocConfigProperties springDocConfigProperties() { + return new SpringDocConfigProperties(); +} + +@Bean +ObjectMapperProvider objectMapperProvider(SpringDocConfigProperties springDocConfigProperties){ + return new ObjectMapperProvider(springDocConfigProperties); +} +---- + +* Then configure, the path of your custom UI yaml file. +[source,properties] +---- +springdoc.swagger-ui.url=/api-docs.yaml +---- + +=== Is there a way to send authorization header through the @Parameter tag? +* The OpenAPI 3 specification does not allow explicitly adding Authorization header. +`Note: Header parameters named Accept, Content-Type and Authorization are not allowed. To describe these headers` +* For more information, you can read: +** link:https://swagger.io/docs/specification/describing-parameters/#header-parameters[https://swagger.io/docs/specification/describing-parameters/#header-parameters, window="_blank"] + +=== My Rest Controller using @Controller annotation is ignored? +* This is the default behaviour if your `@Controller` doesn't have annotation `@ResponseBody` +* You can change your controllers to `@RestControllers`. Or add `@ResponseBody` + `@Controller`. +* If its not possible, you can configure springdoc to scan you additional controller using SpringDocUtils. For example: + +[source,java] +---- +static { + SpringDocUtils.getConfig().addRestControllers(HelloController.class); +} +---- + +=== How can I define groups using application.yml? +* You can load groups dynamically using spring-boot configuration files. +* Note that, for this usage, you don't have to declare the **GroupedOpenApi** Bean. +* You need to declare the following properties, under the prefix **springdoc.group-configs**. +* For example: +[source,properties] +---- +springdoc.group-configs[0].group=users +springdoc.group-configs[0].paths-to-match=/user/** +springdoc.group-configs[0].packages-to-scan=test.org.springdoc.api +---- +* The list of properties under this prefix, are available here: +** link:index.html#properties[springdoc-openapi-properties] + +=== How can I extract fields from parameter object? +* You can use springdoc annotation @ParameterObject. +* Request parameter annotated with @ParameterObject will help adding each field of the parameter as a separate request parameter. +* This is compatible with Spring MVC request parameters mapping to POJO object. +* This annotation does not support nested parameter objects. +* POJO object must contain getters for fields with mandatory prefix `get`. Otherwise, the swagger documentation will not show the fields of the annotated entity. + +=== How to Integrate Open API 3 with Spring project (not Spring Boot)? +When your application is using spring without (spring-boot), you need to add beans and auto-configuration that are natively provided in spring-boot. + +For example, lets assume you want load the swagger-ui in spring-mvc application: + +* You mainly, need to add the springdoc-openapi module + +[source,xml] +---- + + org.springdoc + springdoc-openapi-ui + last.version + +---- + +* If you don't have the spring-boot and spring-boot-autoconfigure dependencies, you need to add them. And pay attention to the compatibility matrix, between you spring.version and spring-boot.version. For example, in this case (spring.version=5.1.12.RELEASE): + +[source,xml] +---- + + org.springframework.boot + spring-boot + 2.1.11.RELEASE + + + org.springframework.boot + spring-boot-autoconfigure + 2.1.11.RELEASE + +---- + +* Scan for the `springdoc-openapi` 'auto-configuration classes that spring-boot automatically loads for you. +* Depending on your module, you can find them on the file: `spring.factories` of each `springdoc-openapi` module. + +[source,java] +---- +@EnableWebMvc +public class AppInitializer implements WebApplicationInitializer { + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + WebApplicationContext context = getContext(); + servletContext.addListener(new ContextLoaderListener(context)); + ServletRegistration.Dynamic dispatcher = servletContext.addServlet("RestServlet", + new DispatcherServlet(context)); + dispatcher.setLoadOnStartup(1); + dispatcher.addMapping("/*"); + } + + private AnnotationConfigWebApplicationContext getContext() { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.scan("rest"); + context.register(this.getClass(), org.springdoc.webmvc.ui.SwaggerConfig.class, + org.springdoc.core.SwaggerUiConfigProperties.class, org.springdoc.core.SwaggerUiOAuthProperties.class, + org.springdoc.webmvc.core.SpringDocWebMvcConfiguration.class, + org.springdoc.webmvc.core.MultipleOpenApiSupportConfiguration.class, + org.springdoc.core.SpringDocConfiguration.class, org.springdoc.core.SpringDocConfigProperties.class, + org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration.class); + + return context; + } +} +---- + +* Depending on your module, you can find them on the file: `spring.factories` of each `springdoc-openapi` module. +* For groups usage make sure your `GroupedOpenApi` Beans are scanned. +* If additionally, you are using custom `context path`: `/my-servlet-path`. Make sure you declare the following property: +[source,properties] +---- +spring.mvc.servlet.path=/my-servlet-path +---- + + +=== How can I use the last `springdoc-openapi` SNAPSHOT ? +* For testing purposes only, you can test temporarily using the last `springdoc-openapi` SNAPSHOT +* To achieve that, configure your pom.xml file with the following `` section: + +[source,xml] +---- + + + Central Portal Snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + +---- + +=== How can I use enable `springdoc-openapi` MonetaryAmount support? +* If an application wants to enable the `springdoc-openapi` support, it declares: + +[source,java] +---- +SpringDocUtils.getConfig().replaceWithClass(MonetaryAmount.class, org.springdoc.core.converters.models.MonetaryAmount.class); +---- + +* Another solution, without using springdoc-openapi MonetaryAmount, would be: + +[source,java] +---- +SpringDocUtils.getConfig().replaceWithSchema(MonetaryAmount.class, new ObjectSchema() + .addProperties("amount", new NumberSchema()).example(99.96) + .addProperties("currency", new StringSchema().example("USD"))); +---- + +=== How can i aggregate external endpoints (exposing OPENAPI 3 spec) inside one single application? +The properties `springdoc.swagger-ui.urls.*`, are suitable to configure external (/v3/api-docs url). +For example, if you want to aggregate all the endpoints of other services, inside one single application. +IMPORTANT: Don't forget that CORS needs to be enabled as well. + +=== How can use custom json/yml file instead of generated one? +If your file open-api.json, contains the OpenAPI documentation in OpenAPI 3 format. +Then simply declare: The file name can be anything you want, from the moment your declaration is consistent yaml or json OpenAPI Spec. +[source,properties] +---- + springdoc.swagger-ui.url=/open-api.json +---- + +Then the file open-api.json, should be located in: src/main/resources/static +No additional configuration is needed. + +=== How can i enable CSRF support? +If you are using standard headers. (For example, using spring-security headers) +If the CSRF Token is required, swagger-ui automatically sends the new XSRF-TOKEN during each HTTP REQUEST. + +If your XSRF-TOKEN isn't standards-based, you can use a requestInterceptor to manually capture and attach the latest xsrf token to requests programmatically via spring resource transformer: + +* link:https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md#requestinterceptor[https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md#requestinterceptor, window="_blank"] + +Starting from release v1.4.4 of springdoc-openapi, a new property is added to enable CSRF support, while using standard header names: +[source,properties] +---- +springdoc.swagger-ui.csrf.enabled=true +---- + +=== How can i disable the default swagger petstore URL? +You can use the following property: +[source,properties] +---- +springdoc.swagger-ui.disable-swagger-default-url=true +---- + +=== Is @PageableDefault supported, to enhance the OpenAPI 3 documentation? +Yes, you can use it in conjunction with `@ParameterObject` annotation. +Also, the spring-boot `spring.data.web.*` and `spring.data.rest.default.*` properties are supported since v1.4.5 + +=== How can I make spring security login-endpoint visible? +You can use the following property: +[source,properties] +---- +springdoc.show-login-endpoint=true +---- + +=== How can I show schema definitions even if the schema is not referenced? +You can use the following property: +[source,properties] +---- +springdoc.remove-broken-reference-definitions=false +---- + +=== How to override @Deprecated? +The whole idea of `springdoc-openapi` is to get your documentation the closest to the code, with minimal code changes. +If the code contains `@Deprecated`, `sprindoc-openapi` will consider its schema as Deprecated as well. +If you want to declare a field on swagger as non deprecated, even with the java code, the field contains `@Depreacted`, +You can use the following property that is available since release v1.4.3: +[source,properties] +---- +springdoc.model-converters.deprecating-converter.enabled=false +---- + +=== How can i display a method that returns ModelAndView? + +You can use the following property: +[source,properties] +---- +springdoc.model-and-view-allowed=true +---- + + +=== How can i have pretty-printed output of the OpenApi specification? + +You can use the following property: +[source,properties] +---- +springdoc.writer-with-default-pretty-printer=true +---- + +=== How can i define different schemas for the same class? +Complex objects are always resolved as a reference to a schema defined in components. +For example, let's consider a `Instance` class with an `workAddress` and `homeAddress` attribute of type `Address`: + +[source,java] +---- +public class PersonDTO { + + @JsonProperty + private String email; + + @JsonProperty + private String firstName; + + @JsonProperty + private String lastName; + + @Schema(ref = "WorkAddressSchema") + @JsonProperty + private Address workAddress; + + @Schema(ref = "HomeAddressSchema") + @JsonProperty + private Address homeAddress; + +} + +public class Address { + + @JsonProperty + private String addressName; + +} +---- + +If you want to define two different schemas for this class, you can set up 2 different schemas as follow: + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI() { + return new OpenAPI().components(new Components() + .addSchemas("WorkAddressSchema", getSchemaWithDifferentDescription(Address.class, "work Address")) + .addSchemas("HomeAddressSchema", getSchemaWithDifferentDescription(Address.class, "home Address"))); +} + +private Schema getSchemaWithDifferentDescription(Class className, String description) { + ResolvedSchema resolvedSchema = ModelConverters.getInstance() + .resolveAsResolvedSchema( + new AnnotatedType(className).resolveAsRef(false)); + return resolvedSchema.schema.description(description); +} +---- + +=== How can i define different description for a class attribute depending on usage? +For example, let's consider a `Instance` class with an `email` attribute: + +[source,java] +---- +public class PersonDTO { + + @JsonProperty + private String email; + + @JsonProperty + private String firstName; + + @JsonProperty + private String lastName; + + +} +---- + +If you want to define two different description for the `email`, you can set up 2 different schemas as follow: + +[source,java] +---- +@Bean +public OpenAPI customOpenAPI() { + return new OpenAPI().components(new Components() + .addSchemas("PersonDTO1", getFieldSchemaWithDifferentDescription(PersonDTO.class, "work email")) + .addSchemas("PersonDTO2", getFieldSchemaWithDifferentDescription(PersonDTO.class, "home email"))); +} + +private Schema getFieldSchemaWithDifferentDescription(Class className, String description) { + ResolvedSchema resolvedSchema = ModelConverters.getInstance() + .resolveAsResolvedSchema( + new AnnotatedType(className).resolveAsRef(false)); + return resolvedSchema.schema.addProperties("email", new StringSchema().description(description)); +} +---- + +=== Customizing swagger static resources + +You can customize swagger documentation static resources located in `META-INF/resources/webjars/swagger-ui/{swagger.version}/`. The list of resources includes: + +- `index.html` +- `swagger-ui-bundle.js` +- `swagger-ui.css` +- `swagger-ui-standalone-preset.js` +- `swagger-ui.css.map` +- `swagger-ui-bundle.js.map` +- `swagger-ui-standalone-preset.js.map` +- `favicon-32x32.png` + +To do this, you need to extend the implementation of `SwaggerIndexPageTransformer` + +[source,java] +---- +public class SwaggerCodeBlockTransformer + extends SwaggerIndexPageTransformer { + // < constructor > + @Override + public Resource transform(HttpServletRequest request, + Resource resource, + ResourceTransformerChain transformer) + throws IOException { + if (resource.toString().contains("swagger-ui.css")) { + final InputStream is = resource.getInputStream(); + final InputStreamReader isr = new InputStreamReader(is); + try (BufferedReader br = new BufferedReader(isr)) { + final String css = br.lines().collect(Collectors.joining()); + final byte[] transformedContent = css.replace("old", "new").getBytes(); + return new TransformedResource(resource, transformedContent); + } // AutoCloseable br > isr > is + } + return super.transform(request, resource, transformer); + } + +} +---- + +Next, add transformer `@Bean` to your `@Configuration` + +[source,java] +---- +@Configuration +public class OpenApiConfig { + @Bean + public SwaggerIndexTransformer swaggerIndexTransformer( + SwaggerUiConfigProperties a, + SwaggerUiOAuthProperties b, + SwaggerUiConfigParameters c, + SwaggerWelcomeCommon d) { + return new SwaggerCodeBlockTransformer(a, b, c, d); + } +} +---- + +Illustrative example + +image::img/static_content_transformation.png[Illustrative example] + +=== What is the compatibility matrix of `springdoc-openapi` with `spring-boot` ? +`springdoc-openapi` is compatible with `spring-boot 1` and `spring-boot 2`. + +In general, **you should only pick the last stable version as per today {springdoc-legacy-version}.** + +More precisely, this the exhaustive list of spring-boot versions against which `springdoc-openapi` has been built: + +|=== +| spring-boot Versions | Minimum springdoc-openapi Versions + +|`3.0.x` | `2.0.x`+ +|`2.7.x`, `1.5.x` | `1.6.11`+ +|`2.6.x`, `1.5.x` | `1.6.0`+ +|`2.5.x`, `1.5.x` | `1.5.9`+ +|`2.4.x`, `1.5.x` | `1.5.0`+ +|`2.3.x`, `1.5.x` | `1.4.0`+ +|`2.2.x`, `1.5.x` | `1.2.1`+ +|`2.0.x`, `1.5.x` | `1.0.0`+ + +|=== + +=== Why am i getting an error: `Swagger UI unable to render definition`, when overriding the default spring registered `HttpMessageConverter`? +When overriding the default spring-boot registered `HttpMessageConverter`, you should have `ByteArrayHttpMessageConverter` registered as well to have proper `springdoc-openapi` support. + +[source,java] +---- + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder.build())); +---- +NOTE: Order is very important, when registering `HttpMessageConverters`. + diff --git a/src/docs/asciidoc/v1/favicon.ico b/src/docs/asciidoc/v1/favicon.ico new file mode 100644 index 0000000..0dfbcd7 Binary files /dev/null and b/src/docs/asciidoc/v1/favicon.ico differ diff --git a/src/docs/asciidoc/v1/features.adoc b/src/docs/asciidoc/v1/features.adoc new file mode 100644 index 0000000..2b12c02 --- /dev/null +++ b/src/docs/asciidoc/v1/features.adoc @@ -0,0 +1,181 @@ +[[features]] +== Springdoc-openapi Features + +=== Adding API Information and Security documentation +The library uses spring-boot application auto-configured packages to scan for the following annotations in spring beans: OpenAPIDefinition and Info. +These annotations declare, API Information: Title, version, licence, security, servers, tags, security and externalDocs. +For better performance of documentation generation, declare @OpenAPIDefinition and @SecurityScheme annotations within a spring managed bean. + +=== Error Handling for REST using @ControllerAdvice +To generate documentation automatically, make sure all the methods declare the HTTP Code responses using the annotation: @ResponseStatus + +=== Disabling the `springdoc-openapi` endpoints +In order to disable the `springdoc-openapi` endpoint (/v3/api-docs by default) use the following property: +[source,properties] +---- +# Disabling the /v3/api-docs endpoint +springdoc.api-docs.enabled=false +---- + +=== Disabling the swagger-ui +In order to disable the swagger-ui, use the following property: +[source,properties] +---- +# Disabling the swagger-ui +springdoc.swagger-ui.enabled=false +---- + +=== Swagger-ui configuration +The library supports the swagger-ui official properties: + +* link:https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/[https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/, window="_blank"] + +You need to declare swagger-ui properties as spring-boot properties. +All these properties should be declared with the following prefix: **springdoc.swagger-ui** + +=== Selecting the Rest Controllers to include in the documentation +Additionally, to @Hidden annotation from swagger-annotations, its possible to restrict the generated OpenAPI description using package or path configuration. + +For the list of packages to include, use the following property: +[source,properties] +---- +# Packages to include +springdoc.packagesToScan=com.package1, com.package2 +---- + +For the list of paths to include, use the following property: +[source,properties] +---- +# Paths to include +springdoc.pathsToMatch=/v1, /api/balance/** +---- + +=== Spring-webflux/WebMvc.fn with Functional Endpoints +Since version v1.5.0, a functional DSL has been introduced, thanks to this enhancement in the spring-framework: link:https://github.com/spring-projects/spring-framework/issues/25938[#25938] + +It's an alternative functional API to the `@RouterOperations` annotations. + +This is a sample DSL, to generate OpenAPI description to the webflux/WebMvc.fn REST endpoints: + +[source,java] +---- +@Bean +RouterFunction routes() { + return route().GET("/foo", HANDLER_FUNCTION, ops -> ops + .operationId("hello") + .parameter(parameterBuilder().name("key1").description("My key1 description")) + .parameter(parameterBuilder().name("key2").description("My key2 description")) + .response(responseBuilder().responseCode("200").description("This is normal response description")) + .response(responseBuilder().responseCode("404").description("This is another response description")) + ).build(); +} +---- + +Here is the link for some sample codes: + +- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app90/HelloRouter.java[HelloRouter] +- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app90/quotes/QuotesRouter.java[QuotesRouter] +- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app90/book/BookRouter.java[BookRouter] +- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app90/employee/EmployeeRouter.java[EmployeeRouter] +- link:https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app90/position/PositionRouter.java[PositionRouter] + +And the Demo code, using the functional endpoints DSL: + +- link:https://github.com/springdoc/springdoc-openapi-demos/tree/master/springdoc-openapi-spring-boot-2-webflux-functional[Sample webflux application using functional DSL] + +Since version `v1.3.8`, the support of functional endpoints has been added. +Two main annotations have been added for this purpose: `@RouterOperations` and `@RouterOperation`. + +Only REST APIs with the `@RouterOperations` and `@RouterOperation` can be displayed on the swagger-ui. + +* `@RouterOperation`: It can be used alone, if the Router bean contains one single route related to the REST API.. +When using @RouterOperation, its not mandatory to fill the path + +* `@RouterOperation`, can reference directly a spring Bean (beanClass property) and the underlying method (beanMethod property): Springdoc-openapi, will then inspect this method and the swagger annotations on this method level. + +[source,java] +---- +@Bean +@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees") +RouterFunction getAllEmployeesRoute() { + return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)), + req -> ok().body( + employeeService().findAllEmployees(), Employee.class)); +} +---- + +* `@RouterOperation`, contains the `@Operation` annotation. +The `@Operation` annotation can also be placed on the bean method level if the property beanMethod is declared. + +IMPORTANT: Don't forget to set **operationId** which is **mandatory**. + +[source,java] +---- +@Bean +@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" }, + parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") }, + responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))), + @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"), + @ApiResponse(responseCode = "404", description = "Employee not found") })) +RouterFunction getEmployeeByIdRoute() { + return route(GET("/employees/{id}"), + req -> ok().body( + employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); +} +---- + +* `@RouterOperations`: This annotation should be used if the Router bean contains multiple routes. +When using RouterOperations, its mandatory to fill the path property. + +* A `@RouterOperations`, contains many `@RouterOperation`. + +[source,java] +---- +@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"), + @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"), + @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"), + @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") }) +@Bean +public RouterFunction personRoute(PersonHandler handler) { + return RouterFunctions + .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) + .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save) + .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete); +} +---- + +All the documentations filled using @RouterOperation, might be completed by the router function data. +For that, `@RouterOperation` fields must help identify uniquely the concerned route. +`springdoc-openpi` scans for a unique route related to a `@RouterOperation` annotation, using on the following criteria: + +* by path +* by path and RequestMethod +* by path and produces +* by path and consumes +* by path and RequestMethod and produces +* by path and RequestMethod and consumes +* by path and produces and consumes +* by path and RequestMethod and produces and consumes + +Some code samples are available on GITHUB of demos: + +* link:https://github.com/springdoc/springdoc-openapi-demos/tree/master/springdoc-openapi-spring-boot-2-webflux-functional[Sample application with Functional Endpoints documentation, window="_blank"] + +And some project tests: (from app69 to app75) + +* link:https://github.com/springdoc/springdoc-openapi/tree/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api[Sample code with Functional Endpoints documentation, window="_blank"] + +=== Integration with WildFly + +* For WildFly users, you need to add the following dependency to make the swagger-ui work: + +[source,xml] +---- + + org.webjars + webjars-locator-jboss-vfs + 0.1.0 + +---- + diff --git a/src/docs/asciidoc/v1/getting-started.adoc b/src/docs/asciidoc/v1/getting-started.adoc new file mode 100644 index 0000000..b4f3015 --- /dev/null +++ b/src/docs/asciidoc/v1/getting-started.adoc @@ -0,0 +1,33 @@ +[[getting-started]] +== Getting Started + +For the integration between spring-boot and swagger-ui, add the library to the list of your project dependencies (No additional configuration is needed) + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-ui + {springdoc-legacy-version} + +---- + + +This will automatically deploy swagger-ui to a spring-boot application: + +* Documentation will be available in HTML format, using the official link:https://github.com/swagger-api/swagger-ui.git[swagger-ui jars, window="_blank"] +* The Swagger UI page will then be available at `\http://server:port/context-path/swagger-ui.html` and the OpenAPI description will be available at the following url for json format: `\http://server:port/context-path/v3/api-docs` +** server: The server name or IP +** port: The server port +** context-path: The context path of the application +* Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml + +TIP: For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: . + + +[source,properties] +---- +# swagger-ui custom path +springdoc.swagger-ui.path=/swagger-ui.html +---- + diff --git a/src/docs/asciidoc/v1/index.adoc b/src/docs/asciidoc/v1/index.adoc new file mode 100644 index 0000000..d6c415b --- /dev/null +++ b/src/docs/asciidoc/v1/index.adoc @@ -0,0 +1,51 @@ += springdoc-openapi v{springdoc-legacy-version} +include::v1/_attributes.adoc[] + +IMPORTANT: For *spring-boot v3* support, make sure you use https://springdoc.org[*springdoc-openapi v2*] + +`springdoc-openapi` is on link:https://opencollective.com/springdoc[Open Collective, window="_blank"]. If you ❤️ this project consider becoming a link:https://github.com/sponsors/springdoc[sponsor, window="_blank"]. + +This project is sponsored by +++++ +

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

+++++ + +include::v1/intro.adoc[] + +include::v1/getting-started.adoc[] + +include::v1/modules.adoc[] + +include::v1/features.adoc[] + +include::v1/properties.adoc[] + +include::v1/plugins.adoc[] + +include::v1/demos.adoc[] + +include::v1/migrating-from-springfox.adoc[] + +include::v1/other-resources.adoc[] + +include::v1/sponsor.adoc[] + +include::v1/thanks.adoc[] + +include::v1/faq.adoc[] \ No newline at end of file diff --git a/src/docs/asciidoc/v1/intro.adoc b/src/docs/asciidoc/v1/intro.adoc new file mode 100644 index 0000000..8a15af9 --- /dev/null +++ b/src/docs/asciidoc/v1/intro.adoc @@ -0,0 +1,26 @@ +[[Introduction]] +== Introduction + +`springdoc-openapi` java library helps to automate the generation of API documentation using spring boot projects. +`springdoc-openapi` works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations. + +Automatically generates documentation in JSON/YAML and HTML format APIs. +This documentation can be completed by comments using swagger-api annotations. + +This library supports: + +* OpenAPI 3 +* Spring-boot (v1, v2 and v3) +* JSR-303, specifically for @NotNull, @Min, @Max, and @Size. +* Swagger-ui +* OAuth 2 +* GraalVM native images + +The following video introduces the Library: + +[link=https://youtu.be/utRxyPfFlDw,window=_blank] +image::img/springdoc-openapi-prez.gif[spring.io conference] + + +This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal). + diff --git a/src/docs/asciidoc/v1/migrating-from-springfox.adoc b/src/docs/asciidoc/v1/migrating-from-springfox.adoc new file mode 100644 index 0000000..890b435 --- /dev/null +++ b/src/docs/asciidoc/v1/migrating-from-springfox.adoc @@ -0,0 +1,114 @@ +[[migrating-from-springfox]] +== Migrating from SpringFox + +* Remove springfox and swagger 2 dependencies. Add `springdoc-openapi-ui` dependency instead. + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-ui + {springdoc-legacy-version} + +---- + +* Replace swagger 2 annotations with swagger 3 annotations (it is already included with `springdoc-openapi-ui` dependency). +Package for swagger 3 annotations is `io.swagger.v3.oas.annotations`. + +- `@Api` -> `@Tag` +- `@ApiIgnore` -> `@Parameter(hidden = true)` or `@Operation(hidden = true)` or `@Hidden` +- `@ApiImplicitParam` -> `@Parameter` +- `@ApiImplicitParams` -> `@Parameters` +- `@ApiModel` -> `@Schema` +- `@ApiModelProperty(allowEmptyValue = true)` -> `@Schema(nullable = true)` +- `@ApiModelProperty` -> `@Schema` +- `@ApiOperation(value = "foo", notes = "bar")` -> `@Operation(summary = "foo", description = "bar")` +- `@ApiParam` -> `@Parameter` +- `@ApiResponse(code = 404, message = "foo")` -> `@ApiResponse(responseCode = "404", description = "foo")` + +* If you're using an object to capture multiple request query params, annotation that method argument with `@ParameterObject` + +* This step is optional: Only if you have **multiple** `Docket` beans replace them with `GroupedOpenApi` beans. + +Before: + +[source,java, subs="attributes+"] +---- + @Bean + public Docket publicApi() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public")) + .paths(PathSelectors.regex("/public.*")) + .build() + .groupName("springshop-public") + .apiInfo(apiInfo()); + } + + @Bean + public Docket adminApi() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin")) + .paths(PathSelectors.regex("/admin.*")) + .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class)) + .build() + .groupName("springshop-admin") + .apiInfo(apiInfo()); + } +---- + +Now: + +[source,java, subs="attributes+"] +---- + @Bean + public GroupedOpenApi publicApi() { + return GroupedOpenApi.builder() + .group("springshop-public") + .pathsToMatch("/public/**") + .build(); + } + @Bean + public GroupedOpenApi adminApi() { + return GroupedOpenApi.builder() + .group("springshop-admin") + .pathsToMatch("/admin/**") + .addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class)) + .build(); + } +---- + +If you have **only one** `Docket` -- remove it and instead add properties to your `application.properties`: + +[source,properties, subs="attributes+"] +---- +springdoc.packagesToScan=package1, package2 +springdoc.pathsToMatch=/v1, /api/balance/** +---- + +* Add bean of `OpenAPI` type. See example: + +[source,java, subs="attributes+"] +---- + @Bean + public OpenAPI springShopOpenAPI() { + return new OpenAPI() + .info(new Info().title("SpringShop API") + .description("Spring shop sample application") + .version("v0.0.1") + .license(new License().name("Apache 2.0").url("http://springdoc.org"))) + .externalDocs(new ExternalDocumentation() + .description("SpringShop Wiki Documentation") + .url("https://springshop.wiki.github.org/docs")); + } +---- + +* If the swagger-ui is served behind a proxy: + ** link:index.html#how-can-i-deploy-springdoc-openapi-ui-behind-a-reverse-proxy[how-can-i-deploy-springdoc-openapi-ui-behind-a-reverse-proxy] +* To customise the Swagger UI + ** link:index.html#how-can-i-configure-swagger-ui[how-can-i-configure-swagger-ui] +* To hide an operation or a controller from documentation + ** link:index.html#how-can-i-hide-an-operation-or-a-controller-from-documentation[how-can-i-hide-an-operation-or-a-controller-from-documentation] + + diff --git a/src/docs/asciidoc/v1/modules.adoc b/src/docs/asciidoc/v1/modules.adoc new file mode 100644 index 0000000..f0f2a94 --- /dev/null +++ b/src/docs/asciidoc/v1/modules.adoc @@ -0,0 +1,296 @@ +[[modules]] +== Springdoc-openapi Modules + +=== General overview +image::img/common.jpg[Architecture] + +=== Spring WebMvc support + +* Documentation will be available at the following url for json format: `\http://server:port/context-path/v3/api-docs` +** server: The server name or IP +** port: The server port +** context-path: The context path of the application +* Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml +* Add the library to the list of your project dependencies. (No additional configuration is needed) + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-webmvc-core + {springdoc-legacy-version} + +---- + +NOTE: This dependency is relevant if you want to generate the OpenAPI description without using the swagger-ui. + +TIP: For custom path of the OpenAPI documentation in Json format, add a custom springdoc property, in your spring-boot configuration file: + +[source,properties, subs="attributes+"] +---- +# /api-docs endpoint custom path +springdoc.api-docs.path=/api-docs +---- + + +=== Spring WebFlux support + +* Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yaml +* Add the library to the list of your project dependencies (No additional configuration is needed) + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-webflux-ui + {springdoc-legacy-version} + +---- + + +=== Spring Hateoas support +The support for Spring Hateoas is available using the dependency springdoc-openapi-hateoas. +The projects that use Spring Hateoas should combine this dependency with the springdoc-openapi-ui dependency. +This dependency enables the support of Spring Hateoas format. + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-hateoas + {springdoc-legacy-version} + +---- + +=== Spring Data Rest support + +The projects that use `spring-data-rest` can add the following dependency in combination with the `springdoc-openapi-ui` dependency. +This dependency enables the support of `spring-boot-starter-data-rest` types like: `@RepositoryRestResource` and `QuerydslPredicate` annotations. + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-data-rest + {springdoc-legacy-version} + +---- + +=== Spring Security support +For a project that uses spring-security, you should add the following dependency, in combination with the springdoc-openapi-ui dependency: +This dependency helps ignoring @AuthenticationPrincipal in case its used on REST Controllers. + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-security + {springdoc-legacy-version} + +---- + +=== Actuator support + +* In order to display `spring-boot-actuator` endpoints, simply add the following property: + +[source,properties] +---- +springdoc.show-actuator=true +---- + +Starting from the release `1.5.1`, it will be possible to expose the **swagger-ui** and the **openapi** endpoints on **actuator port**. + +NOTE: The actuator management port has to be different from the application port. + +To expose the swagger-ui, on the management port, you should set + +[source,properties] +---- +springdoc.use-management-port=true +# This property enables the openapi and swagger-ui endpoints to be exposed beneath the actuator base path. +management.endpoints.web.exposure.include=openapi, swagger-ui +---- + +Once enabled, you should also be able to see the springdoc-openapi endpoints under: (host and port depends on your settings) +- `\http://serverName:managementPort/actuator` + +For example, if you have the following settings: + +Two endpoints will be available: + +. REST API that holdes the OpenAPI definition: + +- `\http://serverName:managementPort/actuator/openapi` + +. An Endpoint, that routes to the swagger-ui: + +- `\http://serverName:managementPort/actuator/swagger-ui` + +[source,properties] +---- +management.server.port=9090 +---- + +For the example, you should also be able to see the springdoc-openapi endpoints: + +- `\http://serverName:9090/actuator` +- `\http://serverName:9090/actuator/swagger-ui` +- `\http://serverName:9090/actuator/openapi` + +All the path `springdoc-openapi` properties are not applicable when `springdoc.use-management-port=true`. + +TIP: If you want to reach the application endpoints, from the swagger-ui deployed beneath the actuator base path, using a different port from your application, `CORS for your endpoints` on your application level should be enabled. + + +Additionally, it is also possible to combine this property, with the existing property to display the actuator endpoints in the swagger-ui. + +[source,properties] +---- +springdoc.show-actuator=true +---- + +Once enabled: +- A dedicated group for the actuator endpoints will be by default added. +- If no group is defined for the application, a default one will be added. + +The swagger-ui will be then accessible through the actuator port: + +- `\http://serverName:managementPort/actuator/swagger-ui` + +If the management port is different from the application port and `springdoc.use-management-port` is not defined but `springdoc.show-actuator` is set to true: + +- The swagger-ui will be then accessible through the application port. For example: `\http://serverName:applicationPort/swagger-ui.html` +- A dedicated group for the actuator endpoints will be by default added. +- If no group is defined for the application, a default one will be added. + + +TIP: If you want to reach the actuator endpoints for this case (different port from your application), `CORS` for your actuator endpoints should be enabled. + +Note: The naming of these new endpoints beneath the actuator base path cannot be customized for now. + +=== Spring Cloud Function Web support + +`spring-cloud-function-web` exposes Java Function as REST endpoint automatically. +* Since version `v1.6.3`, the support of functional endpoints has been added. + +* These starters will display the OpenAPI description of the `spring-cloud-function-web` endpoints. +- If you are using `spring-web`, simply add the `springdoc-openapi-ui` dependency. +- If you are using `spring-webflux`, simply add the `springdoc-openapi-webflux-ui` dependency. + + +The customisation of the output can be achieved programmatically through `OpenApiCustomizer` or with the annotations: `@RouterOperations` and `@RouterOperation`. +For annotation usage, you have: +* `@RouterOperation`: It can be used alone, if the customisation is related to a single REST API. +When using `@RouterOperation`, it's not mandatory to fill the path + +* `@RouterOperation`, contains the `@Operation` annotation. +The `@Operation` annotation can also be placed on the bean method level if the property beanMethod is declared. + +IMPORTANT: Don't forget to set **operationId** which is **mandatory**. + +[source,java] +---- +@Bean +@RouterOperation(operation = @Operation(description = "Say hello", operationId = "hello", tags = "persons", + responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = PersonDTO.class))))) +public Supplier helloSupplier() { + return () -> new PersonDTO(); +} +---- + +* `@RouterOperations`: This annotation should be used to describe the multiple REST APIs exposed by `spring-cloud-function-web`. +When using `RouterOperations`, it's mandatory to fill the method property. + +* A `@RouterOperations`, contains many `@RouterOperation`. + +[source,java] +---- +@Bean +@RouterOperations({ + @RouterOperation(method = RequestMethod.GET, operation = @Operation(description = "Say hello GET", operationId = "lowercaseGET", tags = "persons")), + @RouterOperation(method = RequestMethod.POST, operation = @Operation(description = "Say hello POST", operationId = "lowercasePOST", tags = "positions")) +}) +public Function, Flux> lowercase() { + return flux -> flux.map(value -> value.toLowerCase()); +} +---- + +Some code samples are available on GITHUB of demos: + +* link:https://github.com/springdoc/springdoc-openapi-demos/tree/master/springdoc-openapi-spring-cloud-function[Sample applications with Spring Cloud Function Web, window="_blank"] + + +=== Kotlin support +For a project that uses Kotlin, you should add the following dependency. +This dependency improves the support of Kotlin types: + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-kotlin + {springdoc-legacy-version} + +---- + +* If you are using spring-web, you should combine the `springdoc-openapi-kotlin` module with `springdoc-openapi-ui`. +* If you are using spring-webflux, you should combine the `springdoc-openapi-kotlin` module with `springdoc-openapi-webflux-ui`. + +=== Groovy support +For a project that uses Groovy, you should add the following dependency, in combination with the springdoc-openapi-ui dependency: +This dependency improves the support of Kotlin types: + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-groovy + {springdoc-legacy-version} + +---- + +=== Javadoc support +For a project that wants to enable javadoc support, you should add the following dependency, in combination with the `springdoc-openapi-ui` dependency: + +[source,xml, subs="attributes+"] +---- + + org.springdoc + springdoc-openapi-javadoc + {springdoc-legacy-version} + +---- + +This dependency improves the support of javadoc tags and comments: + +- The javadoc comment of a method: is resolved as the `@Operation` description +- ``@return ``: is resolved as the `@Operation` response description +- The javadoc comment of an attribute: is resolved as '@Schema' description for this field. + +This dependency is based on the library https://github.com/dnault/therapi-runtime-javadoc[therapi-runtime-javadoc] + +NOTE: Make sure, you enable the annotation processor of `therapi-runtime-javadoc` in order to enable javadoc support for springdoc-openapi. + +[source,xml, subs="attributes+"] +---- + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + com.github.therapi + therapi-runtime-javadoc-scribe + 0.15.0 + + + + + + +---- + +TIP: If both a swagger-annotation description and a javadoc comment are present. The value of the swagger-annotation description will be used. + diff --git a/src/docs/asciidoc/v1/other-resources.adoc b/src/docs/asciidoc/v1/other-resources.adoc new file mode 100644 index 0000000..2f1c64f --- /dev/null +++ b/src/docs/asciidoc/v1/other-resources.adoc @@ -0,0 +1,26 @@ +[[other-resources]] +== Other resources + +=== Additional resources to get started +- link:https://prezi.com/view/r4DP4TCmYUJk1eaqjKG4/[Springdoc-openapi presentation, window="_blank"] +- link:https://www.baeldung.com/spring-rest-openapi-documentation[Baeldung, window="_blank"] +- link:https://dzone.com/articles/openapi-3-documentation-with-spring-boot[DZone Part1, window="_blank"] +- link:https://dzone.com/articles/doing-more-with-springdoc-openapi[DZone Part2, window="_blank"] +- link:https://dzone.com/articles/extending-swagger-and-spring-doc-open-api[Extending Swagger and Spring Doc Open API, window="_blank"] +- link:https://piotrminkowski.com/2020/02/20/microservices-api-documentation-with-springdoc-openapi/[Piotrminkowski Blog, window="_blank"] + + +=== Dependencies repository + +The `springdoc-openapi` libraries are hosted on maven central repository. +The artifacts can be viewed accessed at the following locations: + +Releases: + +* link:https://central.sonatype.com/search?q=g:org.springdoc[https://central.sonatype.com/search?q=g:org.springdoc, window="_blank"] + +Snapshots: + +* link:https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/org/springdoc/[https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/org/springdoc/, window="_blank", window="_blank"] + + diff --git a/src/docs/asciidoc/v1/plugins.adoc b/src/docs/asciidoc/v1/plugins.adoc new file mode 100644 index 0000000..6a1e7c8 --- /dev/null +++ b/src/docs/asciidoc/v1/plugins.adoc @@ -0,0 +1,81 @@ +[[plugins]] +== Springdoc-openapi Plugins + +=== Maven plugin + +The aim of `springdoc-openapi-maven-plugin` is to generate json and yaml OpenAPI description during build time. +The plugin works during integration-tests phase, and generate the OpenAPI description. +The plugin works in conjunction with spring-boot-maven plugin. + +You can test it during the integration tests phase using the maven command: + +[source,bash] +---- +mvn verify +---- + +In order to use this functionality, you need to add the plugin declaration on the plugins section of your pom.xml: + +[source,xml] +---- + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + -Dspring.application.admin.enabled=true + + + + + start + stop + + + + + + org.springdoc + springdoc-openapi-maven-plugin + 1.5 + + + integration-test + + generate + + + + +---- + +For more custom settings of the springdoc-openapi-maven-plugin, you can consult the plugin documentation: + +* link:https://github.com/springdoc/springdoc-openapi-maven-plugin[https://github.com/springdoc/springdoc-openapi-maven-plugin, window="_blank"] + +=== Gradle plugin + +This plugin allows you to generate an OpenAPI 3 specification for a Spring Boot application from a Gradle build. + +[source,groovy] +---- +plugins { + id("org.springframework.boot") version "2.7.0" + id("org.springdoc.openapi-gradle-plugin") version "1.9.0" +} +---- + +When you add this plugin and its runtime dependency plugins to your build file, the plugin creates the following tasks: + +* forkedSpringBootRun +* generateOpenApiDocs + +[source,bash] +---- +gradle clean generateOpenApiDocs +---- + +For more custom configuration of `springdoc-openapi-gradle-plugin` ,you can consult the plugin documentation: + +* link:https://github.com/springdoc/springdoc-openapi-gradle-plugin[https://github.com/springdoc/springdoc-openapi-gradle-plugin, window="_blank"] + diff --git a/src/docs/asciidoc/v1/privacy-policy.adoc b/src/docs/asciidoc/v1/privacy-policy.adoc new file mode 100644 index 0000000..8363f6f --- /dev/null +++ b/src/docs/asciidoc/v1/privacy-policy.adoc @@ -0,0 +1,146 @@ +Privacy Policy + +Within the entire Springdoc organization and while accessing the website www.springdoc.org, your privacy is one of our fundamental commitments, and therefore, we take utmost care to process your personal data in accordance with the principles set forth in the applicable legislation, including without limitation the General Data Protection Regulation no. 679/2016 (“GDPR”). + +Each time we are required by the applicable law or, otherwise, want to use this legal basis, we will request your free, informed, specific, and unequivocal consent for the processing of your Personal Data. By expressing your consent, you agree that we can collect, use, reveal, process and transfer your Personal Data in accordance with this Policy. + +We reserve the right to amend the provisions of this Policy from time to time. If we make changes to this Policy, we will make the updated version available on the Site, and we will update the “Last updated” date. We will also inform you of the changes that have occurred to ensure that you are aware of how we use your Personal Data. Any amendments to this Policy will apply on the date that they are made, with the exception of changes that require your prior consent and which will apply as of the moment when you express such consent. + +For the avoidance of any doubt, we are not obliged to inform you by using the contact details associated with your account on the Site with respect to any and all of the changes to this Policy. + +1. CATEGORIES OF PERSONAL DATA, PURPOSES OF PROCESSING, AND LEGAL GROUNDS + +You can contact us in different ways: by support form or by using our chat. In this case, in general, we will process the following Personal Data: first name, last name, email, and any other information you voluntarily provide when you contact us, depending on the topic of the chat, such as personal data resulting from the questions regarding our tutorials that you may raise on any subject of interest. + +When you contact us by using our chat, we might also process your Personal Data included in your Site profile. + +Purpose of processing Legal ground +In this situation, we will use your Personal Data only to contact you in connection with the requested offer or in connection with the resolution of the problem. Processing is necessary for the performance of a contract to which the data subject is a party or in order to take steps at the request of the data subject prior to entering into a contract (art. 6 para. 1, let. b GDPR); +1.1. Marketing messages + +You can opt-in to receive marketing messages via email. + +Purpose of processing Legal ground +If you opt to receive such marketing messages, we will use your email address to send you marketing messages about our activities and promotions. Your consent. (art. 6 para. 1, let. a GDPR). +You can revoke your prior consent at all times and without any costs, with altering consequences for the future. + +1.2. Analytical data + +When using our Site, we process certain information regarding your activity in order to analyze the use of our Site. Such information includes, for example, your navigation, your IP, or your geolocation. + +This information is not collected in order to be associated with identified persons. However, insofar such information leads to the identification of a user, the provisions of this Policy shall become applicable. + +Purpose of processing Legal ground +We use this data for the sole purpose of obtaining anonymous statistical information concerning the use of the Site. Our legitimate interest in the improvement of our Site (art. 6 para. 1, let. f GDPR); +1.3. Sensitive personal data + +We do not collect any Sensitive Personal Data about you. Sensitive data refers to data that includes details about your race or ethnicity, religious or philosophical beliefs, sex life, sexual orientation, political opinions, trade union membership, information about your health, and genetic and biometric data. We do not collect any information about criminal convictions and offenses. + +Where we are required to collect personal data by law or under the terms of the contract between us, and you do not provide us with that data when requested, we may not be able to perform the contract (for example, to deliver goods or services to you). If you don’t provide us with the requested data, we may have to cancel a product or service you have ordered, but if we do, we will notify you at the time. + +We will only use your personal data for a purpose it was collected for or a reasonably compatible purpose if necessary. For more information on this, please email us at support@springdoc.org. In case we need to use your details for an unrelated new purpose, we will let you know and explain the legal grounds for processing. + +We may process your personal data without your knowledge or consent where this is required or permitted by law. + +We do not carry out automated decision-making or any type of automated profiling. + + +2. FAILURE TO PROVIDE PERSONAL DATA + +You may refuse to provide certain Personal Data (indicated above), but, in such a case, you may not be able to benefit from certain Site services and features, including, but not limited to, the creation of a user account, acquiring a tutorial or It course or contacting you to solve your problem and to provide support. + + + +3. PROCESSING PERSONAL DATA BASED ON OUR LEGITIMATE INTEREST + +When we process on the lawful basis of legitimate interest, we apply the following tests to determine whether it is appropriate: + +The purpose test – is there a legitimate interest behind the processing? +Necessity test – is the processing necessary for that purpose? +Balancing test – is the legitimate interest overridden, or not, by the individual’s interests, rights, or freedoms? +For more information on how we process the Personal Data on the lawful basis of legitimate interest, please contact us at support@springdoc.org. + + + +4. AUTOMATIC PROCESSING OF PERSONAL DATA + +Your Personal Data will not be processed for making decisions based solely on automatic processing that would result in legal effects concerning you or could similarly significantly affect you. + + + +5. STORAGE PERIOD + +As a rule, we will process your Personal Data during the existence of your account in our Site. + +Personal Data collected based on your consent will be processed until the date of withdrawal of the consent. + +In certain circumstances, we may retain your Personal Data for longer periods of time, for example, if we are obliged to do so in accordance with the legal, regulatory, tax, or accounting requirements. + +We may also keep your Personal Data for longer periods of time so that we have accurate records of your dealings with us in the event of any complaints or challenges or if we reasonably believe there is a prospect of litigation relating to your Personal Data or dealings. + + + +6. TRANSFER OF PERSONAL DATA + +Your Personal Data is filed and stored on the servers of our contractual partners that are helping us to provide our services to you. + +We may transfer Personal Data, as far as necessary, to the following categories of recipients: + +contractual partners; +subcontractors; +payment processors; +insurance companies; +companies offering IT services; +software or hardware vendors; +market research companies; +marketing companies; +public authorities, courts of law or arbitral tribunals, and authorities competent to investigate criminal offenses. +These recipients can be located in the European Union and/or in the European Economic Area. Where recipients are located outside the European Union and the European Economic Area, including in countries not recognized as ensuring an adequate level of protection, the transfer of Personal Data shall be carried out only if there are appropriate guarantees in accordance with applicable law. In this respect, we rely on several guarantees, such as the standard contractual clauses issued by the European Commission. You may receive from us a list of recipients from third countries, as well as a copy of the agreed provisions that ensure an adequate level of protection of Personal Data. For any request to this effect, please contact us at the contact details mentioned below. + + + +7. SECURITY + +The security of your Personal Data is important to us. Your Personal Data will therefore be processed by applying reasonable technical and organizational measures to protect Personal Data, such as limiting access to Personal Data, encryption or anonymization of Personal Data, and storage in secure environments. However, despite our efforts, we cannot always guarantee the effectiveness of the security measures implemented, and therefore we cannot guarantee the security of Personal Data at any time. + + + +8. RIGHTS IN CONNECTION WITH THE PROCESSING OF YOUR PERSONAL DATA + +8.1. Your rights + +You have the following rights in connection with the processing of your Personal Data: + +Access right: You have the right to obtain from us confirmation that your Personal Data is processed by us, as well as information on the specific processing, such as: the purposes of the processing, categories of processed Personal Data, recipients of Personal Data, the period for which Personal Data is stored, if we transfer the Personal Data abroad and how we protect it, your rights, the right to lodge a complaint before the supervisory authority, the source of your Personal Data. + +Right to rectification: You have the possibility to request rectification of your Personal Data, provided that the applicable legal requirements are met. In the event of errors, after notification, we will immediately correct your Personal Data. + +Right to erasure: In certain cases, you have the possibility to request the deletion of Personal Data, namely when: (i) the Personal Data are no longer necessary in relation to the purposes for which they were collected or otherwise processed; (ii) you withdraw consent on which the processing is based, and there is no other legal ground for the processing; (iii) you exercise the right to object to the processing; (iv) the Personal Data has been unlawfully processed. We are not obliged to comply with your request when the processing is necessary (among others) for compliance with a legal obligation or for the establishment, exercise, or defense of legal claims. There are also other circumstances in which we are not obliged to comply with this request for the deletion of Personal Data. + +Restriction of processing: You may request us to restrict the processing of your Personal Data in the following circumstances: (i) you contest the accuracy of the Personal Data for a period enabling us to verify the accuracy of the Personal Data; (ii) the processing is unlawful, and then you oppose to the erasure of the Personal Data and request the restriction of their use instead; (iii) we no longer need the Personal Data for the purposes of the processing, but you require them for the establishment, exercise or defense of legal claims; (iv) you have objected to processing, pending the verification whether our legitimate grounds override yours. However, we can continue to process your Personal Data (i) when you consent; (ii) for the establishment, exercise, or defense of legal claims; or (iii) for the protection of the rights of another natural or legal person. + +Right to data portability: Insofar the Personal Data is processed based on your consent or on the execution of the agreement and the processing is carried out by automated means, you have the right to have your data Personal Data provided to you in a structured format, which is currently used and can be read automatically and you have the right to request us to transfer this Personal Data to another controller. This right shall not adversely affect the rights and freedoms of others. + +Right to opposition: In certain situations, such as when we process your Personal Data on the basis of a legitimate interest for the purpose of sending marketing messages, you have the right to object to the processing of your Personal Data by us. In the event of an unjustified objection, the Company is entitled to continue processing Personal Data. + +Revocation of consent: Insofar you consented to the processing of your Personal Data, you can at all times revoke your consent without affecting the lawfulness of processing based on consent before its withdrawal. + +Right not to be subject to any automatic individual decisions: You have the right not to be subject to a decision based solely on automated processing, including profiling, which produces legal effects concerning you or similarly significantly affects you. Such right cannot be exercised when the decision: (i) is necessary for entering into, or performance of, a contract between you and us; (ii) is authorized by law which lays down suitable measures to safeguard your rights and freedoms and legitimate interests; or (iii) is based on your explicit consent. + +Right to lodge a complaint with the supervisory authority: You have the right to lodge a complaint with The National Supervisory Authority for Personal Data Processing (“DPA”) in relation to any breach of your rights regarding the processing of your Personal Data. +8.2. How to exercise your rights + +To learn more about the manner in which you may exercise the aforementioned rights, please contact us at support@springdoc.org. + +Identity verification: We take utmost care of the confidentiality of all Personal Data, and we reserve the right to verify your identity if you make a request in relation to your Personal Data + +Fees: As a rule, you can exercise your rights free of charge. However, we reserve the right to request a reasonable fee if your claims are manifestly unfounded or excessive, in particular, because of their repetitive nature. + +Response Time: We make every effort to respond to your request within one month of receiving the request. This period may be extended by two further months where necessary, taking into account the complexity and number of the requests, in which case we will inform you of any such extension and of the reasons for the delay. + + + +9. CONTACT + +If you have any questions or concerns about this Policy or its implementation, you may contact us at support@springdoc.org. + diff --git a/src/docs/asciidoc/v1/properties.adoc b/src/docs/asciidoc/v1/properties.adoc new file mode 100644 index 0000000..49e7d9b --- /dev/null +++ b/src/docs/asciidoc/v1/properties.adoc @@ -0,0 +1,19 @@ +[[properties]] +== Springdoc-openapi Properties + +`springdoc-openapi` relies on standard link:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config[spring configuration properties, window="_blank"] (yml or properties) using the standard files locations. + + +=== springdoc-openapi core properties + +include::core-properties.adoc[] + +=== swagger-ui properties +- The support of the swagger-ui properties is available on `springdoc-openapi`. See link:https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/[Official documentation, window="_blank"]. + +- You can use the same swagger-ui properties in the documentation as Spring Boot properties. + +NOTE: All these properties should be declared with the following prefix: `springdoc.swagger-ui` + +include::ui-properties.adoc[] + diff --git a/src/docs/asciidoc/v1/sponsor.adoc b/src/docs/asciidoc/v1/sponsor.adoc new file mode 100644 index 0000000..7a55653 --- /dev/null +++ b/src/docs/asciidoc/v1/sponsor.adoc @@ -0,0 +1,52 @@ +[[sponsor]] +== Sponsor + +`springdoc-openapi` is on link:https://opencollective.com/springdoc[Open Collective, window="_blank"]. + +If you ❤️ this project consider becoming a link:https://github.com/sponsors/springdoc[sponsor, window="_blank"]. + +This money is used to cover project expenses and your donation will help the project live and grow successfully. + +Thank you to our bronze sponsors! +++++ +

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

+++++ + + +=== Benefits of being a bronze sponsor +Bronze sponsors donate $50 per month to the project, and get the following benefits: + +- You will receive a Sponsor badge 🎖!. Visibility on the front page of https://springdoc.org in the `welcome` page (about 55,000 views/month on May, 2022). +- “Thank you” tweet from `springdoc team'. + +=== Benefits of being a silver sponsor +Silver sponsors donate $100 per month to the project, and get the following benefits: + +- Same benefits as bronze sponsors (visibility on main pages, and thank you tweet). +- The ability to get support for 2 `issues` every month, non transferable. +- If issues are not created by the end of the month, it is lost + +=== Benefits of being a gold sponsor +Gold sponsors donate $500 per month to the project, and get the following benefits: + +- Same benefits as silver sponsors (visibility on main pages, and thank you tweet). +- The ability to get support for 10 `issues` every month, non transferable. +- Company logos on all https://springdoc.org page footers +- If issues are not created by the end of the month, the remaining ones are lost. + diff --git a/src/docs/asciidoc/v1/thanks.adoc b/src/docs/asciidoc/v1/thanks.adoc new file mode 100644 index 0000000..2034eaf --- /dev/null +++ b/src/docs/asciidoc/v1/thanks.adoc @@ -0,0 +1,9 @@ +[[thanks]] +== Special Thanks + +* Thank you to link:https://spring.io/team[The Spring Team , window="_blank"] for sharing all relevant resources around Spring projects. + +* Thanks a lot link:https://www.jetbrains.com/?from=springdoc-openapi[JetBrains, window="_blank"] for supporting springdoc-openapi project. + +image::https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg[JetBrains logo] + diff --git a/src/docs/asciidoc/v1/ui-properties.adoc b/src/docs/asciidoc/v1/ui-properties.adoc new file mode 100644 index 0000000..943e290 --- /dev/null +++ b/src/docs/asciidoc/v1/ui-properties.adoc @@ -0,0 +1,54 @@ +[[ui-properties]] + +|=== +|Parameter name | Default Value | Description + +|springdoc.swagger-ui.path | `/swagger-ui.html` |`String`, For custom path of the swagger-ui HTML documentation. +|springdoc.swagger-ui.enabled | `true` | `Boolean`. To disable the swagger-ui endpoint (/swagger-ui.html by default). +|springdoc.swagger-ui.configUrl | `/v3/api-docs/swagger-config` | `String`. URL to fetch external configuration document from. +|springdoc.swagger-ui.layout | `BaseLayout` | `String`. The name of a component available via the plugin system to use as the top-level layout for Swagger UI. +|springdoc.swagger-ui.validatorUrl | | By default, Swagger UI does not validate specs. You can use this parameter to set a validator URL, for example for against swagger.io’s online validator. +|springdoc.swagger-ui.tryItOutEnabled | `true` |`Boolean`. Controls whether the "Try it out" section should be enabled by default. +|springdoc.swagger-ui.filter | `false` | `Boolean OR String`. If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be Boolean to enable or disable, or a string, in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag. +|springdoc.swagger-ui.operationsSorter | | `Function=(a => a)`. Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged. +|springdoc.swagger-ui.tagsSorter | | `Function=(a => a)`. Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort[see Array.prototype.sort() , window="_blank"] to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger UI. +|springdoc.swagger-ui.oauth2RedirectUrl | `/swagger-ui/oauth2-redirect.html` | `String`. OAuth redirect URL. +|springdoc.swagger-ui.displayOperationId | `false` | `Boolean`. Controls the display of operationId in operations list. The default is `false`. +|springdoc.swagger-ui.displayRequestDuration | `false` | `Boolean`. Controls the display of the request duration (in milliseconds) for "Try it out" requests. +|springdoc.swagger-ui.deepLinking | `false` | `Boolean`. If set to `true`, enables deep linking for tags and operations. See the [Deep Linking documentation](https://swagger.io/docs/open-source-tools/swagger-ui/usage/deep-linking) for more information. +|springdoc.swagger-ui.defaultModelsExpandDepth | `1` | `Number`. The default expansion depth for models (set to -1 completely hide the models). +|springdoc.swagger-ui.defaultModelExpandDepth | `1` | `Number`. The default expansion depth for the model on the model-example section. +|springdoc.swagger-ui.defaultModelRendering | | `String=["example"*, "model"]`. Controls how the model is shown when the API is first rendered. (The user can always switch the rendering for a given model by clicking the 'Model' and 'Example Value' links.) +|springdoc.swagger-ui.docExpansion | | `String=["list"*, "full", "none"]`. Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). +|springdoc.swagger-ui.maxDisplayedTags | | `Number`. If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations. +|springdoc.swagger-ui.showExtensions | `false` | `Boolean`. Controls the display of vendor extension (`x-`) fields and values for Operations, Parameters, and Schema. +|springdoc.swagger-ui.url | | `String`.To configure, the path of a custom OpenAPI file . Will be ignored if `urls` is used. +|springdoc.swagger-ui.showCommonExtensions | `false` | `Boolean`. Controls the display of extensions (`pattern`, `maxLength`, `minLength`, `maximum`, `minimum`) fields and values for Parameters. +|springdoc.swagger-ui.supportedSubmitMethods | | `Array=[get, put, post, delete, options, head, patch, trace]`. List of HTTP methods that have the "Try it out" feature enabled. An empty array disables "Try it out" for all operations. This does not filter the operations from the display. +|springdoc.swagger-ui.queryConfigEnabled | `false` | `Boolean`. Disabled since `v1.6.0`. This parameter enables (legacy) overriding configuration parameters via URL search params. link:https://github.com/swagger-api/swagger-ui/security/advisories/GHSA-qrmm-w75w-3wpx[See security advisory , window="_blank"] before enabling this feature. +|springdoc.swagger-ui.oauth. additionalQueryStringParams | | `String`. Additional query parameters added to authorizationUrl and tokenUrl. +|springdoc.swagger-ui.disable-swagger-default-url | `false` | `Boolean`. To disable the swagger-ui default petstore url. (Available since v1.4.1). +|springdoc.swagger-ui.urls[0].url | | `URL`. The url of the swagger group, used by Topbar plugin. URLs must be unique among all items in this array, since they're used as identifiers. +|springdoc.swagger-ui.urls[0].name | | `String`. The name of the swagger group, used by Topbar plugin. Names must be unique among all items in this array, since they're used as identifiers. +|springdoc.swagger-ui.urlsPrimaryName | | `String`. The name of the swagger group which will be displayed when Swagger UI loads. +|springdoc.swagger-ui.oauth.clientId | | `String`. Default clientId. MUST be a string. +|springdoc.swagger-ui.oauth.clientSecret | | `String`. Default clientSecret. Never use this parameter in your production environment. It exposes crucial security information. This feature is intended for dev/test environments only. +|springdoc.swagger-ui.oauth.realm | | `String`. realm query parameter (for OAuth 1) added to authorizationUrl and tokenUrl. +|springdoc.swagger-ui.oauth.appName | | `String`. OAuth application name, displayed in authorization popup. +|springdoc.swagger-ui.oauth.scopeSeparator | | `String`. OAuth scope separator for passing scopes, encoded before calling, default value is a space (encoded value %20). +|springdoc.swagger-ui.csrf.enabled | `false` | `Boolean`. To enable CSRF support +|springdoc.swagger-ui.csrf.use-local-storage | `false` | `Boolean`. To get the CSRF token from the Local Storage. +|springdoc.swagger-ui.csrf.use-session-storage | `false` | `Boolean`. To get the CSRF token from the Session Storage. +|springdoc.swagger-ui.csrf.cookie-name | `XSRF-TOKEN` | `String`. Optional CSRF, to set the CSRF cookie name. +|springdoc.swagger-ui.csrf.header-name | `X-XSRF-TOKEN` | `String`. Optional CSRF, to set the CSRF header name. +|springdoc.swagger-ui.syntaxHighlight.activated | `true` | `Boolean`. Whether syntax highlighting should be activated or not. +|springdoc.swagger-ui.syntaxHighlight.theme | `agate` | `String`. `String=["agate"*, "arta", "monokai", "nord", "obsidian", "tomorrow-night"]`. link:https://highlightjs.org/static/demo/[Highlight.js, window="_blank"] syntax coloring theme to use. (Only these 6 styles are available.) +|springdoc.swagger-ui.oauth. useBasicAuthentication WithAccessCodeGrant | `false` | `Boolean`. Only activated for the accessCode flow. During the authorization_code request to the tokenUrl, pass the Client Password using the HTTP Basic Authentication scheme (Authorization header with Basic base64encode(client_id + client_secret)). +|springdoc.swagger-ui.oauth. usePkceWithAuthorization CodeGrant | `false` | `Boolean`.Only applies to authorizatonCode flows. Proof Key for Code Exchange brings enhanced security for OAuth public clients. +|springdoc.swagger-ui.persistAuthorization | `false` | `Boolean`. If set to true, it persists authorization data and it would not be lost on browser close/refresh +|springdoc.swagger-ui.use-root-path | `false` | `Boolean`. If set to true, the swagger-ui will be accessible from the application root path directly. + +|=== + + + diff --git a/src/main/resources/index.md b/src/main/resources/index.md deleted file mode 100644 index 49920b9..0000000 --- a/src/main/resources/index.md +++ /dev/null @@ -1,403 +0,0 @@ ---- -layout: default ---- -![Octocat](https://springdoc.org/assets/images/springdoc-openapi.png) - -# **Introduction** - -springdoc-openapi java library helps automating the generation of API documentation using spring boot projects. -springdoc-openapi works by examining an application at runtime to infer API semantics based on spring configurations, class structure and various annotations. - -Automatically generates documentation in JSON/YAML and HTML format APIs. -This documentation can be completed by comments using swagger-api annotations. - -This library supports: -* OpenAPI 3 -* Spring-boot (v1 and v2) -* JSR-303, specifically for @NotNull, @Min, @Max, and @Size. -* Swagger-ui -* OAuth 2 - -The following video introduces the Library: - -[![Watch the video](https://springdoc.org/assets/images/springdoc-openapi-prez.gif)](https://youtu.be/utRxyPfFlDw) - -This is a community-based project, not maintained by the Spring Framework Contributors (Pivotal). - -# **Getting Started** -![overview](https://springdoc.org/assets/images/common.jpg) - -## Integration between spring-boot and swagger-ui -* Automatically deploys swagger-ui to a spring-boot application -* Documentation will be available in HTML format, using the official [swagger-ui jars](https://github.com/swagger-api/swagger-ui.git). -* The Swagger UI page should then be available at http://server:port/context-path/swagger-ui.html and the OpenAPI description will be available at the following url for json format: http://server:port/context-path/v3/api-docs - * server: The server name or IP - * port: The server port - * context-path: The context path of the application -* Documentation can be available in yaml format as well, on the following path : /v3/api-docs.yml -* Add the library to the list of your project dependencies (No additional configuration is needed) - -```xml - - org.springdoc - springdoc-openapi-ui - ${springdoc.version} - -``` -* This step is optional: For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: - -```properties -# swagger-ui custom path -springdoc.swagger-ui.path=/swagger-ui.html -``` - -## Integration of the library in a spring-boot project without the swagger-ui: -* Documentation will be available at the following url for json format: http://server:port/context-path/v3/api-docs - * server: The server name or IP - * port: The server port - * context-path: The context path of the application -* Documentation will be available in yaml format as well, on the following path : /v3/api-docs.yml -* Add the library to the list of your project dependencies. (No additional configuration is needed) - -```xml - - org.springdoc - springdoc-openapi-webmvc-core - ${springdoc.version} - -``` -* This step is optional: For custom path of the OpenAPI documentation in Json format, add a custom springdoc property, in your spring-boot configuration file: - -```properties -# /api-docs endpoint custom path -springdoc.api-docs.path=/api-docs -``` - -* For WildFly users, you need to add the following dependency to make the swagger-ui work: - -```xml - - org.webjars - webjars-locator-jboss-vfs - 0.1.0 - -``` - -# **Additional settings** - -## Adding API Information and Security documentation - The library uses spring-boot application auto-configured packages to scan for the following annotations in spring beans: OpenAPIDefinition and Info. - These annotations declare, API Information: Title, version, licence, security, servers, tags, security and externalDocs. - For better performance of documentation generation, declare @OpenAPIDefinition and @SecurityScheme annotations within a spring managed bean. - -## Error Handling for REST using @ControllerAdvice -To generate documentation automatically, make sure all the methods declare the HTTP Code responses using the annotation: @ResponseStatus - -## Disabling the springdoc-openapi endpoints -In order to disable the springdoc-openapi endpoint (/v3/api-docs by default) use the following property: -```properties -# Disabling the /v3/api-docs enpoint -springdoc.api-docs.enabled=false -``` - -## Disabling the swagger-ui -In order to disable the swagger-ui, use the following property: -```properties -# Disabling the swagger-ui -springdoc.swagger-ui.enabled=false -``` -## Swagger-ui configuration -The library supports the swagger-ui official properties: -- [https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/](https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/) - -You need to declare swagger-ui properties as spring-boot properties. -All these properties should be declared with the following prefix: **springdoc.swagger-ui** - -## Selecting the Rest Controllers to include in the documentation -Additionally to @Hidden annotation from swagger-annotations, its possible to restrict the generated OpenAPI description using package or path configuration. - -For the list of packages to include, use the following property: -```properties -# Packages to include -springdoc.packagesToScan=com.package1, com.package2 -``` - -For the list of paths to include, use the following property: -```properties -# Paths to include -springdoc.pathsToMatch=/v1, /api/balance/** -``` - -## Spring-webflux support with Annotated Controllers -* Documentation can be available in yaml format as well, on the following path : /v3/api-docs.yml -* Add the library to the list of your project dependencies (No additional configuration is needed) - -```xml - - org.springdoc - springdoc-openapi-webflux-ui - ${springdoc.version} - -``` -* This step is optional: For custom path of the swagger documentation in HTML format, add a custom springdoc property, in your spring-boot configuration file: - -```properties -# swagger-ui custom path -springdoc.swagger-ui.path=/swagger-ui.html -``` - - -## Spring-webflux/WebMvc.fn with Functional Endpoints -Since version v1.3.8, the support of functional endpoints has been added. -Two main annotations have been added for this purpose: @RouterOperations and @RouterOperation. - -Only REST APIs with the @RouterOperations and @RouterOperation can be displayed on the swagger-ui. - -* @RouterOperation: It can be used alone, if the Router bean contains one single route related to the REST API.. - When using @RouterOperation, its not mandatory to fill the path - -* @RouterOperation, can reference directly a spring Bean (beanClass property) and the underlying method (beanMethod property): Springdoc-openapi, will then inspect this method and the swagger annotations on this method level. - -```java -@Bean -@RouterOperation(beanClass = EmployeeService.class, beanMethod = "findAllEmployees") -RouterFunction getAllEmployeesRoute() { - return route(GET("/employees").and(accept(MediaType.APPLICATION_JSON)), - req -> ok().body( - employeeService().findAllEmployees(), Employee.class)); -} -``` - -* @RouterOperation, contains the @Operation annotation. - The @Operation annotation can also be placed on the bean method level if the property beanMethod is declared. - -* Don't forget to set **operationId** which is **mandatory**. - -```java -@Bean -@RouterOperation(operation = @Operation(operationId = "findEmployeeById", summary = "Find purchase order by ID", tags = { "MyEmployee" }, - parameters = { @Parameter(in = ParameterIn.PATH, name = "id", description = "Employee Id") }, - responses = { @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Employee.class))), - @ApiResponse(responseCode = "400", description = "Invalid Employee ID supplied"), - @ApiResponse(responseCode = "404", description = "Employee not found") })) -RouterFunction getEmployeeByIdRoute() { - return route(GET("/employees/{id}"), - req -> ok().body( - employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); -} -``` - -* @RouterOperations: This annotation should be used if the Router bean contains multiple routes. - When using RouterOperations, its mandatory to fill the path property. - -* A @RouterOperations, contains many @RouterOperation. - -```java -@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"), - @RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"), - @RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"), - @RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") }) -@Bean -public RouterFunction personRoute(PersonHandler handler) { - return RouterFunctions - .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) - .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) - .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save) - .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete); -} -``` - -All the documentations filled using @RouterOperation, might be completed by the router function data. -For that, @RouterOperation fields must help identify uniquely the concerned route. -springdoc-openpi scans for a unique route related to a @RouterOperation annotation, using on the following criteria: -- by path -- by path and RequestMethod -- by path and produces -- by path and consumes -- by path and RequestMethod and produces -- by path and RequestMethod and consumes -- by path and produces and consumes -- by path and RequestMethod and produces and consumes - -Some code samples are available on GITHUB of demos: - -- [Sample application with Functional Endpoints documentation](https://github.com/springdoc/springdoc-openapi-demos/tree/master/springdoc-openapi-spring-boot-2-webflux-functional) - -And some of the project tests: (from app69 to app75) - -- [Sample code with Functional Endpoints documentation](https://github.com/springdoc/springdoc-openapi/tree/master/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api) - -## Spring Hateoas support -The support for Spring Hateoas is available using the dependency springdoc-openapi-hateoas. -The projects that use Spring Hateoas should combine this dependency with the springdoc-openapi-ui dependency. -This dependency enables the support of Spring Hateoas format. -```xml - - org.springdoc - springdoc-openapi-hateoas - ${springdoc.version} - -``` - -## Spring Data Rest support -The support for Pageable of spring-data-commons is available. -If only want to enable the support of spring Pageable Type, you can just enable it using: - -```java -SpringDocUtils.getConfig().replaceWithClass(org.springframework.data.domain.Pageable.class, -org.springdoc.core.converters.models.Pageable.class); -``` - -Alternately, the projects that use Pageable type can aslo add the follwing dependency together with the springdoc-openapi-ui dependency. -This dependency enables the support of spring-data-rest types as well: @RepositoryRestResource and QuerydslPredicate annotations. -```xml - - org.springdoc - springdoc-openapi-data-rest - ${springdoc.version} - -``` - -## Spring security support -For a project that uses spring-security, you should add the following dependency, together with the springdoc-openapi-ui dependency: -This dependency helps ignoring @AuthenticationPrincipal in case its used on REST Controllers. -```xml - - org.springdoc - springdoc-openapi-security - ${springdoc.version} - -``` - -## Kotlin support -For a project that uses Kotlin, you should add the following dependency. -This dependency improves the support of Kotlin types: -```xml - - org.springdoc - springdoc-openapi-kotlin - ${springdoc.version} - -``` -- If your are using spring-web, you combine the springdoc-openapi-kotlin module with springdoc-openapi-ui. -- If your are using spring-webflux, you combine the springdoc-openapi-kotlin module with springdoc-openapi-webflux-ui. - -## Groovy support -For a project that uses Groovy, you should add the following dependency, together with the springdoc-openapi-ui dependency: -This dependency improves the support of Kotlin types: -```xml - - org.springdoc - springdoc-openapi-groovy - ${springdoc.version} - -``` - - -## Introduction to springdoc-openapi-maven-plugin - -The aim of springdoc-openapi-maven-plugin is to generate json and yaml OpenAPI description during build time. -The plugin works during integration-tests phase, and generate the OpenAPI description. -The plugin works in conjunction with spring-boot-maven plugin. - -You can test it during the integration tests phase using the maven command: - -```protobuf -mvn verify -``` - -In order to use this functionality, you need to add the plugin declaration on the plugins section of your pom.xml: - -```xml - - org.springframework.boot - spring-boot-maven-plugin - 2.3.4.RELEASE - - -Dspring.application.admin.enabled=true - - - - pre-integration-test - - start - - - - post-integration-test - - stop - - - - - - org.springdoc - springdoc-openapi-maven-plugin - 1.1 - - - integration-test - - generate - - - - -``` - -For more custom settings of the springdoc-openapi-maven-plugin, you can consult the plugin documentation: -- [https://github.com/springdoc/springdoc-openapi-maven-plugin](https://github.com/springdoc/springdoc-openapi-maven-plugin) - -## Introduction to springdoc-openapi-gradle-plugin - -This plugin allows you to generate an OpenAPI 3 specification for a Spring Boot application from a Gradle build. - -```groovy -plugins { - id("org.springframework.boot") version "2.3.0.RELEASE" - id("com.github.johnrengelman.processes") version "0.5.0" - id("org.springdoc.openapi-gradle-plugin") version "1.3.0" -} -``` - -When you add this plugin and its runtime dependency plugins to your build file, the plugin creates the following tasks: -- forkedSpringBootRun -- generateOpenApiDocs - -```slim -gradle clean generateOpenApiDocs -``` - -For more custom configuration of springdoc-openapi-gradle-plugin ,you can consult the plugin documentation: -- [https://github.com/springdoc/springdoc-openapi-gradle-plugin](https://github.com/springdoc/springdoc-openapi-gradle-plugin) - -# **springdoc applications demos** - -## [Demo Spring Boot 2 Web MVC with OpenAPI 3](http://158.101.164.60:8081/). -## [Demo Spring Boot 2 WebFlux with OpenAPI 3](http://158.101.164.60:8082/). -## [Demo Spring Boot 1 Web MVC with OpenAPI 3](http://158.101.164.60:8083/). -## [Demo Spring Boot 2 WebFlux with Functional endpoints OpenAPI 3](http://158.101.164.60:8084/swagger-ui.html). -## [Demo Spring Boot 2 and Spring Hateoas with OpenAPI 3](http://158.101.164.60:8085/swagger-ui.html). - -![Branching](https://springdoc.org/assets/images/pets.png) - -## Source code of the Demo Applications -* [https://github.com/springdoc/springdoc-openapi-demos.git](https://github.com/springdoc/springdoc-openapi-demos.git) - -## Dependencies repository - -The springdoc-openapi libraries are hosted on maven central repository. -The artifacts can be viewed accessed at the following locations: - -Releases: -* [https://oss.sonatype.org/content/groups/public/org/springdoc/](https://oss.sonatype.org/content/groups/public/org/springdoc/). - -Snapshots: -* [https://oss.sonatype.org/content/repositories/snapshots/org/springdoc/](https://oss.sonatype.org/content/repositories/snapshots/org/springdoc/). - -# **Thank you for the support** - -* Thanks a lot [JetBrains](https://www.jetbrains.com/?from=springdoc-openapi) for supporting springdoc-openapi project. - -![Octocat](https://springdoc.org/assets/images/jetbrains.svg) diff --git a/src/main/resources/migrating-from-springfox.md b/src/main/resources/migrating-from-springfox.md deleted file mode 100644 index 616a6e9..0000000 --- a/src/main/resources/migrating-from-springfox.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -layout: default ---- - -

Migrating from SpringFox

- -+ Remove springfox and swagger 2 dependencies. Add `springdoc-openapi-ui` dependency instead. - -```xml - - org.springdoc - springdoc-openapi-ui - @springdoc.version@ - -``` - -+ Replace swagger 2 annotations with swagger 3 annotations (it is already included with `springdoc-openapi-ui` dependency). -Package for swagger 3 annotations is `io.swagger.v3.oas.annotations`. - - - `@Api` -> `@Tag` - - `@ApiIgnore` -> `@Parameter(hidden = true)` or `@Operation(hidden = true)` or `@Hidden` - - `@ApiImplicitParam` -> `@Parameter` - - `@ApiImplicitParams` -> `@Parameters` - - `@ApiModel` -> `@Schema` - - `@ApiModelProperty(hidden = true)` -> `@Schema(accessMode = READ_ONLY)` - - `@ApiModelProperty` -> `@Schema` - - `@ApiOperation(value = "foo", notes = "bar")` -> `@Operation(summary = "foo", description = "bar")` - - `@ApiParam` -> `@Parameter` - - `@ApiResponse(code = 404, message = "foo")` -> `@ApiResponse(responseCode = "404", description = "foo")` - -+ This step is optional: Only if you have **multiple** `Docket` beans replace them with `GroupedOpenApi` beans. - - Before: - ```java - @Bean - public Docket publicApi() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public")) - .paths(PathSelectors.regex("/public.*")) - .build() - .groupName("springshop-public") - .apiInfo(apiInfo()); - } - - @Bean - public Docket adminApi() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin")) - .paths(PathSelectors.regex("/admin.*")) - .build() - .groupName("springshop-admin") - .apiInfo(apiInfo()); - } - ``` - Now: - ```java - @Bean - public GroupedOpenApi publicApi() { - return GroupedOpenApi.builder() - .setGroup("springshop-public") - .pathsToMatch("/public/**") - .build(); - } - - @Bean - public GroupedOpenApi adminApi() { - return GroupedOpenApi.builder() - .setGroup("springshop-admin") - .pathsToMatch("/admin/**") - .build(); - } - ``` - If you have **only one** `Docket` -- remove it and instead add properties to your `application.properties`: - ```properties - springdoc.packagesToScan=package1, package2 - springdoc.pathsToMatch=/v1, /api/balance/** - ``` -+ Add bean of `OpenAPI` type. See example: - ```java - @Bean - public OpenAPI springShopOpenAPI() { - return new OpenAPI() - .info(new Info().title("SpringShop API") - .description("Spring shop sample application") - .version("v0.0.1") - .license(new License().name("Apache 2.0").url("http://springdoc.org"))) - .externalDocs(new ExternalDocumentation() - .description("SpringShop Wiki Documentation") - .url("https://springshop.wiki.github.org/docs")); - } - ``` - - + If the swagger-ui is served behind a proxy: - * [https://springdoc.org/faq.html#how-can-i-deploy-the-doploy-springdoc-openapi-ui-behind-a-reverse-proxy](https://springdoc.org/faq.html#how-can-i-deploy-the-doploy-springdoc-openapi-ui-behind-a-reverse-proxy). - - + To customise the Swagger UI - * [https://springdoc.org/faq.html#how-can-i-configure-swagger-ui](https://springdoc.org/faq.html#how-can-i-configure-swagger-ui). - - + To hide an operation or a controller from documentation - * [https://springdoc.org/faq.html#how-can-i-hide-an-operation-or-a-controller-from-documentation-](https://springdoc.org/faq.html#how-can-i-hide-an-operation-or-a-controller-from-documentation-). - diff --git a/thumbnail.png b/thumbnail.png deleted file mode 100644 index d06bb2a..0000000 Binary files a/thumbnail.png and /dev/null differ