diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index f3ab0a3f..3dc7326b 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ["17"] + java: ["8"] steps: - uses: actions/checkout@v2 diff --git a/docs/pom.xml b/docs/pom.xml index 4422b0ac..913bf194 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud.internal releaser-parent - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT releaser-docs pom @@ -16,11 +16,11 @@ releaser.* - + ${project.groupId} releaser-core diff --git a/pom.xml b/pom.xml index 85f63bf5..91c51619 100644 --- a/pom.xml +++ b/pom.xml @@ -6,13 +6,13 @@ org.springframework.cloud.internal releaser-parent - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT pom org.springframework.cloud spring-cloud-build - 4.0.3 + 3.1.1 @@ -28,17 +28,18 @@ UTF-8 - 17 + 1.8 - 2022.0.3 - 1.315 + 2021.0.1 + 1.1.2 0.0.9 + 7.0.4.Final - 6.5.0.202303070854-r + 5.12.0.202106070339-r 3.8.5 2.10.0 - 4.3.1 + 4.3.0 0.12.0 4.2.0 1.0.0-SNAPSHOT @@ -46,7 +47,6 @@ 5.0.4 1.1.0 1.12 - 4.11.0 @@ -58,93 +58,6 @@ pom import - - org.eclipse.jgit - org.eclipse.jgit - ${org.eclipse.jgit-version} - - - org.eclipse.jgit - org.eclipse.jgit.ssh.jsch - ${org.eclipse.jgit-version} - - - - com.jcraft - jsch.agentproxy.sshagent - ${jsch-agent.version} - - - com.jcraft - jsch.agentproxy.jsch - ${jsch-agent.version} - - - com.jcraft - jsch.agentproxy.usocket-jna - ${jsch-agent.version} - - - org.apache.maven - maven-model - - - ${maven-model.version} - - - org.codehaus.mojo - versions-maven-plugin - ${versions-maven-plugin.version} - - - org.slf4j - slf4j-jdk14 - - - org.slf4j - jcl-over-slf4j - - - org.slf4j - slf4j-nop - - - - - org.kohsuke - github-api - ${github-api.version} - - - com.squareup.okhttp3 - okhttp - ${okhttp.version} - - - com.github.jknack - handlebars - ${handlebars.version} - - - io.spring.initializr - initializr-metadata - ${initializr-metadata.version} - - - org.glassfish - javax.json - ${javax.json.version} - - - org.zeroturnaround - zt-exec - ${zt.exec.version} - - - org.awaitility - awaitility - ${awaitility.version} - @@ -190,12 +103,20 @@ false + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + spring-snapshots Spring Snapshots - https://repo.spring.io/snapshot + https://repo.spring.io/libs-snapshot-local true @@ -206,7 +127,15 @@ spring-milestones Spring Milestones - https://repo.spring.io/milestone + https://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/libs-release-local false diff --git a/projects/pom.xml b/projects/pom.xml index 26896f47..097e0054 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -5,19 +5,20 @@ 4.0.0 releaser-projects - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT pom org.springframework.cloud.internal releaser-parent - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT .. spring-cloud spring-cloud-stream + reactor diff --git a/projects/reactor/.jdk8 b/projects/reactor/.jdk8 new file mode 100644 index 00000000..e69de29b diff --git a/projects/reactor/pom.xml b/projects/reactor/pom.xml new file mode 100644 index 00000000..d482ecff --- /dev/null +++ b/projects/reactor/pom.xml @@ -0,0 +1,107 @@ + + + 4.0.0 + + reactor + jar + + + org.springframework.cloud.internal + releaser-projects + 2.0.0-SNAPSHOT + .. + + + + UTF-8 + 1.8 + 5.7.0.RELEASE + + + + + org.springframework.cloud.internal + releaser-spring + ${project.version} + + + org.cloudfoundry + cloudfoundry-client-reactor + ${cloudfoundry-client.version} + + + org.cloudfoundry + cloudfoundry-operations + ${cloudfoundry-client.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + sonar + + + + org.jacoco + jacoco-maven-plugin + + + pre-unit-test + + prepare-agent + + + surefireArgLine + ${project.build.directory}/jacoco.exec + + + + post-unit-test + test + + report + + + + ${project.build.directory}/jacoco.exec + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${surefireArgLine} + + + + + + + + diff --git a/projects/reactor/src/main/java/releaser/ReleaserApplication.java b/projects/reactor/src/main/java/releaser/ReleaserApplication.java new file mode 100644 index 00000000..cafb9dd5 --- /dev/null +++ b/projects/reactor/src/main/java/releaser/ReleaserApplication.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser; + +import releaser.internal.options.Parser; +import releaser.internal.spring.ExecutionResultHandler; +import releaser.internal.spring.SpringReleaser; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ReleaserApplication extends ReleaserCommandLineRunner { + + public ReleaserApplication(SpringReleaser releaser, ExecutionResultHandler executionResultHandler, Parser parser) { + super(releaser, executionResultHandler, parser); + } + + public static void main(String[] args) { + SpringApplication application = new SpringApplication(ReleaserApplication.class); + application.setWebApplicationType(WebApplicationType.NONE); + application.run(args); + } + +} diff --git a/projects/reactor/src/main/java/releaser/reactor/CfConfiguration.java b/projects/reactor/src/main/java/releaser/reactor/CfConfiguration.java new file mode 100644 index 00000000..baa95d95 --- /dev/null +++ b/projects/reactor/src/main/java/releaser/reactor/CfConfiguration.java @@ -0,0 +1,78 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import org.cloudfoundry.client.CloudFoundryClient; +import org.cloudfoundry.doppler.DopplerClient; +import org.cloudfoundry.operations.DefaultCloudFoundryOperations; +import org.cloudfoundry.reactor.ConnectionContext; +import org.cloudfoundry.reactor.DefaultConnectionContext; +import org.cloudfoundry.reactor.TokenProvider; +import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient; +import org.cloudfoundry.reactor.doppler.ReactorDopplerClient; +import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider; +import org.cloudfoundry.reactor.uaa.ReactorUaaClient; +import org.cloudfoundry.uaa.UaaClient; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +/** + * @author Simon Baslé + */ +@Configuration +@Profile("production") +class CfConfiguration { + + @Bean + DefaultConnectionContext connectionContext(@Value("${cf.apiHost}") String apiHost) { + return DefaultConnectionContext.builder().apiHost(apiHost).build(); + } + + @Bean + PasswordGrantTokenProvider tokenProvider(@Value("${cf.username}") String username, + @Value("${cf.password}") String password) { + return PasswordGrantTokenProvider.builder().password(password).username(username).build(); + } + + @Bean + ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { + return ReactorCloudFoundryClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider) + .build(); + } + + @Bean + ReactorDopplerClient dopplerClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { + return ReactorDopplerClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider).build(); + } + + @Bean + ReactorUaaClient uaaClient(ConnectionContext connectionContext, TokenProvider tokenProvider) { + return ReactorUaaClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider).build(); + } + + @Bean + DefaultCloudFoundryOperations defaultCloudFoundryOperations(CloudFoundryClient cloudFoundryClient, + DopplerClient dopplerClient, UaaClient uaaClient, @Value("${cf.organization}") String organizationId, + @Value("${cf.space}") String spaceId) { + return DefaultCloudFoundryOperations.builder().cloudFoundryClient(cloudFoundryClient) + .dopplerClient(dopplerClient).uaaClient(uaaClient).organization(organizationId).space(spaceId).build(); + } + +} diff --git a/projects/reactor/src/main/java/releaser/reactor/GenerateReleaseNotesTask.java b/projects/reactor/src/main/java/releaser/reactor/GenerateReleaseNotesTask.java new file mode 100644 index 00000000..0caebefa --- /dev/null +++ b/projects/reactor/src/main/java/releaser/reactor/GenerateReleaseNotesTask.java @@ -0,0 +1,579 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import javax.json.JsonObject; +import javax.json.JsonValue; + +import com.jcabi.github.Coordinates; +import com.jcabi.github.Github; +import com.jcabi.github.Issue; +import com.jcabi.github.Issues; +import com.jcabi.github.Release; +import com.jcabi.github.Repo; +import com.jcabi.github.RepoCommit; +import com.jcabi.github.RepoCommits; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import releaser.internal.git.ProjectGitHandler; +import releaser.internal.git.SimpleCommit; +import releaser.internal.spring.Arguments; +import releaser.internal.tasks.DryRunReleaseReleaserTask; +import releaser.internal.tasks.ProjectPostReleaseReleaserTask; +import releaser.internal.tasks.release.PushChangesReleaseTask; +import releaser.internal.tech.BuildUnstableException; +import releaser.internal.tech.ExecutionResult; + +/** + * @author Simon Baslé + */ +public class GenerateReleaseNotesTask implements ProjectPostReleaseReleaserTask, DryRunReleaseReleaserTask { + + private static final Logger log = LoggerFactory.getLogger(GenerateReleaseNotesTask.class); + + private static final String NAME = "releaseNotes"; + + private static final String SHORTNAME = "rn"; + + private final Github github; + + private final ProjectGitHandler gitHandler; + + public GenerateReleaseNotesTask(Github github, ProjectGitHandler gitHandler) { + this.github = github; + this.gitHandler = gitHandler; + } + + @Override + public int getOrder() { + return PushChangesReleaseTask.ORDER + 5; + } + + @Override + public String name() { + return NAME; + } + + @Override + public String shortName() { + return SHORTNAME; + } + + @Override + public String header() { + return "Generating release notes"; + } + + @Override + public String description() { + return "Generates the release notes as a Github release draft, from issues and commits"; + } + + @Override + public ExecutionResult runTask(Arguments args) throws BuildUnstableException, RuntimeException { + if (args.versionFromBom.isSnapshot()) { + log.info("\nWon't generate notes for a snapshot version"); + return ExecutionResult.success(); + } + + Repo repo = github.repos() + .get(new Coordinates.Simple(args.properties.getGit().getOrgName(), args.projectToRun.name())); + + String releaseTag = "v" + args.versionFromBom.version; + if (args.options.dryRun != Boolean.TRUE) { + Optional maybeTagSha1 = gitHandler.findTagSha1(args.project, releaseTag); + if (maybeTagSha1.isPresent()) { + String tagSha1 = maybeTagSha1.get(); + try { + // call json() to trigger fetch of gh tag by SHA1 + repo.git().references().get("tags/" + tagSha1).json(); + } + catch (IOException e) { + return ExecutionResult.failure(new IllegalStateException("Shouldn't create a release if tag " + + releaseTag + " (sha1=" + tagSha1 + ") not visible in Github", e)); + } + } + else { + return ExecutionResult.failure(new IllegalStateException( + "Attempting to draft release note but tag not found in repository: " + releaseTag)); + } + } + + Issues issuesClient = repo.issues(); + EnumMap> entries = new EnumMap<>(Type.class); + + String toVersionTag = "v" + args.versionFromBom.version; + if (args.options.dryRun == Boolean.TRUE && !gitHandler.findTagSha1(args.project, toVersionTag).isPresent()) { + toVersionTag = "HEAD"; + } + + // eg. 3.2.1 for current 3.2.2 + String fromVersionTag = args.versionFromBom.computePreviousPatchTag("v", "RELEASE").orElseGet(() -> { + Pattern pattern = args.versionFromBom.computePreviousMinorTagPattern("v", "RELEASE") + .orElseGet(() -> args.versionFromBom.computePreviousMajorTagPattern("v", "RELEASE")); + // eg. v3.2.*.RELEASE or v3.*.*.RELEASE + log.info("Couldn't simply compute previous version of {}, looking through tag list with pattern {}", + args.versionFromBom.version, pattern.pattern()); + + List sortedTags = gitHandler.findTagNamesMatching(args.project, pattern) + .collect(Collectors.toList()); + if (sortedTags.isEmpty()) { + throw new IllegalStateException("Couldn't find a tag that matches pattern " + pattern.pattern()); + } + sortedTags.forEach(System.out::println); + return sortedTags.get(0); + }); + + if (Boolean.TRUE == args.options.interactive) { + log.info("\nComputed log range is {}..{}", fromVersionTag, toVersionTag); + log.info("\nForce the FROM in log range if needed [{}]", fromVersionTag); + String modifiedFrom = System.console().readLine(); + if (!modifiedFrom.trim().isEmpty()) { + fromVersionTag = modifiedFrom; + } + log.info("\nForce the TO in log range if needed [{}]", toVersionTag); + String modifiedTo = System.console().readLine(); + if (!modifiedTo.trim().isEmpty()) { + toVersionTag = modifiedTo; + } + } + log.info("Will fetch the log for range {}..{}", fromVersionTag, toVersionTag); + + // gather commits. we use tags in the format `vVERSION` + final List revCommits = gitHandler.commitsBetween(args.project, fromVersionTag, toVersionTag); + + // parse and link to issues if possible, determining type + for (SimpleCommit revCommit : revCommits) { + ChangelogEntry entry = parseChangeLogEntry(issuesClient, revCommit); + + for (Type type : entry.types) { + entries.computeIfAbsent(type, t -> new ArrayList<>()).add(entry); + } + } + + // generate the notes + String notes = generateNotes(args, entries, extractContributorMentions(repo, revCommits)); + + if (args.options.dryRun != null && args.options.dryRun) { + // print out + log.info("[Dry-Run] Generated release notes:"); + log.info("\n\n" + notes + "\n\n"); + return ExecutionResult.success(); + } + else { + // WARNING: double check the tag actually exists, otherwise this will create a + // tag :( The verification is done early in the task to avoid fetching + // commits/issues + + Release.Smart draftRelease = null; + JsonObject draftReleaseJson = null; + try { + // attempt to find gh release with this tag. stop at 2 month old releases + Instant oldestReleaseToConsider = ZonedDateTime.now().minusMonths(2).toInstant(); + for (Release release : repo.releases().iterate()) { + JsonObject releaseJson = release.json(); + // seems the created release has a wrong tag "untagged-xxxxx", we also + // look at name + if (releaseJson.getString("tag_name").equals(releaseTag) + || releaseJson.getString("name").equals(releaseTag)) { + if (!releaseJson.getBoolean("draft")) { + return ExecutionResult + .failure(new IllegalStateException("Release already exists for tag " + releaseTag)); + } + else { + draftRelease = new Release.Smart(release); + draftReleaseJson = releaseJson; + break; + } + } + // we didn't find a matching release. don't go too far back in time! + String publishedAtJson = releaseJson.getString("published_at"); + Instant publishedAt = oldestReleaseToConsider.minusSeconds(1); + if (publishedAtJson != null) { + publishedAt = ZonedDateTime.parse(publishedAtJson).toInstant(); + } + if (publishedAt.isBefore(oldestReleaseToConsider)) { + log.info("OK, didn't find a release matching tag " + releaseTag + + " within the last 2 month, stopping there"); + break; + } + } + } + catch (Throwable e) { + return ExecutionResult.failure( + new IllegalStateException("Unable to try to match github releases with tag " + releaseTag, e)); + } + + if (draftReleaseJson == null) { + // create a draft release for the tag + try { + Release.Smart release = new Release.Smart(repo.releases().create(releaseTag)); + release.draft(true); + release.tag(releaseTag); + release.name(releaseTag); + release.body(notes); + if (args.versionFromBom.isMilestone() || args.versionFromBom.isRc()) { + release.prerelease(true); + } + return ExecutionResult.success(); + } + catch (IOException e) { + return ExecutionResult.failure(e); + } + } + else { + // update the existing draft + try { + // edit the release + String oldAndNewNotes = draftReleaseJson.getString("body") + "\n\n----\nNew draft added " + + LocalDateTime.now().toString() + "\n----\n" + notes; + draftRelease.body(oldAndNewNotes); + return ExecutionResult.success(); + } + catch (IOException e) { + return ExecutionResult.failure(e); + } + } + } + } + + /** + * Generate the release notes. + */ + protected String generateNotes(Arguments args, EnumMap> entries, + List contributorGithubMentions) { + // TODO use a template? handlebars ! + StringBuilder notes = new StringBuilder().append(args.projectToRun.name()).append(" `") + .append(args.versionFromBom.version).append("` is part of **`").append(args.releaseTrain().version) + .append("` Release Train**."); + + notes.append("\n\n## :warning: Update considerations and deprecations"); + for (ChangelogEntry noteworthy : entries.getOrDefault(Type.NOTEWORTHY, Collections.emptyList())) { + notes.append("\n - ").append(noteworthy.description); + for (String issueTitle : noteworthy.associatedIssueLinksAndTitles.values()) { + notes.append("\n\t - ").append(cleanupShortMessage(issueTitle)); + } + } + + notes.append("\n\n## :sparkles: New features and improvements"); + for (ChangelogEntry feature : entries.getOrDefault(Type.FEATURE, Collections.emptyList())) { + notes.append("\n - ").append(feature.description); + for (String issueTitle : feature.associatedIssueLinksAndTitles.values()) { + notes.append("\n\t - ").append(cleanupShortMessage(issueTitle)); + } + } + + notes.append("\n\n## :beetle: Bug fixes"); + for (ChangelogEntry bug : entries.getOrDefault(Type.BUG, Collections.emptyList())) { + notes.append("\n - ").append(bug.description); + for (String issueTitle : bug.associatedIssueLinksAndTitles.values()) { + notes.append("\n\t - ").append(cleanupShortMessage(issueTitle)); + } + } + + notes.append("\n\n## :book: Documentation, Tests and Build"); + for (ChangelogEntry misc : entries.getOrDefault(Type.DOC_MISC, Collections.emptyList())) { + notes.append("\n - ").append(misc.description); + for (String issueTitle : misc.associatedIssueLinksAndTitles.values()) { + notes.append("\n\t - ").append(cleanupShortMessage(issueTitle)); + } + } + + notes.append("\n\n## **TODO DISPATCH THESE**"); + for (ChangelogEntry unclassified : entries.getOrDefault(Type.UNCLASSIFIED, Collections.emptyList())) { + notes.append("\n - ").append(unclassified.description); + for (String issueTitle : unclassified.associatedIssueLinksAndTitles.values()) { + notes.append("\n\t - ").append(cleanupShortMessage(issueTitle)); + } + } + + // contributors + notes.append("\n\n## :+1: Thanks to the following contributors that also participated to this release\n"); + notes.append(String.join(", ", contributorGithubMentions)); + + return notes.toString(); + } + + /** + * Categorize into a {@link Type} from a set of labels and the commit's short message + * (eg. in case of specific message prefix). + * @param labels the set of labels found for issues referenced in the commit + * @param shortMessage the commit's title/short message + * @return a {@link Type} categorizing the commit, or {@link Type#UNCLASSIFIED} if not + * clear + */ + protected EnumSet extractTypes(Set labels, String shortMessage) { + List types = new ArrayList<>(); + for (String label : labels) { + switch (label) { + case "type/bug": + types.add(Type.BUG); + break; + case "type/enhancement": + types.add(Type.FEATURE); + break; + case "type/documentation": + case "type/dependency-upgrade": + case "type/chores": + types.add(Type.DOC_MISC); + break; + default: + if (label.startsWith("warn/")) { + types.add(Type.NOTEWORTHY); + } + break; + } + } + + if (shortMessage.startsWith("[build]") || shortMessage.startsWith("[polish]") + || shortMessage.startsWith("[doc]")) { + types.add(Type.DOC_MISC); + } + + if (types.isEmpty()) { + return EnumSet.of(Type.UNCLASSIFIED); + } + return EnumSet.copyOf(types); + } + + protected String commitToGithubMention(RepoCommits commitsClient, SimpleCommit revCommit) { + RepoCommit dumbCommit = commitsClient.get(revCommit.fullSha1); + RepoCommit.Smart smartCommit = new RepoCommit.Smart(dumbCommit); + try { + JsonObject commitJson = smartCommit.json(); + JsonValue.ValueType authorType = commitJson.get("author").getValueType(); + if (authorType == JsonValue.ValueType.OBJECT) { + return "@" + commitJson.getJsonObject("author").getString("login"); + } + else if (authorType == JsonValue.ValueType.NULL) { + // assume author+committer, look under commit.author.name + if (commitJson.containsKey("commit") && commitJson.getJsonObject("commit").containsKey("author")) { + return "@" + commitJson.getJsonObject("commit").getJsonObject("author").getString("name"); + } + } + // in case unexpected json, output the "sha", "commit", "author" and + // "committer" + return "@RAW{\"sha\", " + commitJson.get("sha") + ", \"author\", \"" + commitJson.get("author") + + ", \"committer\", \"" + commitJson.get("committer") + ", \"commit\", \"" + + commitJson.get("commit") + "}"; + } + catch (IOException e) { + return null; + } + } + + /** + * Extract at-mentions of contributors, given a list of commits (will fetch + * contributor login from github). The list is deduplicated and sorted in + * case-insensitive alphabetical order. + */ + List extractContributorMentions(Repo repo, List revCommits) { + RepoCommits commitsClient = repo.commits(); + return revCommits.stream().map(c -> commitToGithubMention(commitsClient, c)).filter(Objects::nonNull).distinct() + .sorted(String.CASE_INSENSITIVE_ORDER).collect(Collectors.toList()); + } + + /** + * Clean up a short message, removing issue links in suffix and pr prefix forms. + */ + protected String cleanupShortMessage(String shortMessage) { + final Matcher shortMessageMatcher = SHORT_MESSAGE.matcher(shortMessage); + if (shortMessageMatcher.matches()) { + return shortMessageMatcher.group(1).trim(); + } + return shortMessage; + } + + /** + * Clean up the short message of a {@link SimpleCommit}, ie detect message prefix like + * "fix #123 Something something (#124)". The prefix up to the issue link is removed, + * and so is the PR reference at the end. + */ + protected String cleanupShortMessage(SimpleCommit commit) { + if (!commit.isMergeCommit) { + return cleanupShortMessage(commit.title); + } + return commit.title; + } + + /** + * Extract issue numbers from links like #123 in the whole commit message, in order. + */ + protected Set extractIssueNumbers(SimpleCommit commit) { + Set issueNumbers = new LinkedHashSet<>(); + Matcher titleIssueMatcher = ISSUE_REF.matcher(commit.title); + while (titleIssueMatcher.find()) { + issueNumbers.add(Integer.valueOf(titleIssueMatcher.group(1))); + } + Matcher bodyIssueMatcher = ISSUE_REF.matcher(commit.fullMessage); + while (bodyIssueMatcher.find()) { + issueNumbers.add(Integer.valueOf(bodyIssueMatcher.group(1))); + } + return issueNumbers; + } + + /** + * From the set of issue numbers (see {@link #extractIssueNumbers(SimpleCommit)}), + * extract github client Issue objects and fetch labels and titles from these issues. + * The labels and titles are injected in a {@link Set} of labels and {@link Map} of + * hashtag issue links to issue titles. + */ + protected void fetchIssueLabelsAndTitles(Issues issueClient, Set issueNumbers, Set labelsTarget, + Map referencedIssuesTarget) { + issueNumbers.forEach(i -> { + try { + // avoid "Smart" issue here as it makes further requests to the server :( + // we have everything handy in the JSON + Issue issue = issueClient.get(i); + JsonObject issueJson = issue.json(); + issueJson.getJsonArray("labels") + .forEach(label -> labelsTarget.add(((JsonObject) label).getString("name"))); + referencedIssuesTarget.put("#" + issueJson.getInt("number"), issueJson.getString("title")); + } + catch (Exception e) { + log.warn("Could not fetch issue information for #" + i, e); + } + }); + } + + /** + * Extract issue information from the commit and generate the {@link ChangelogEntry}. + */ + protected ChangelogEntry parseChangeLogEntry(Issues issueClient, SimpleCommit commit) { + String cleanShortMessage = cleanupShortMessage(commit); + Set issueNumbers = extractIssueNumbers(commit); + + Set labelsTarget = new HashSet<>(); + Map referencedIssuesTarget = new LinkedHashMap<>(); + fetchIssueLabelsAndTitles(issueClient, issueNumbers, labelsTarget, referencedIssuesTarget); + + EnumSet types = extractTypes(labelsTarget, commit.title); + + return new ChangelogEntry(types, commit.abbreviatedSha1, cleanShortMessage, referencedIssuesTarget); + } + + /* + * Pattern specific to reactor commit message convention: `fix #123 Some short + * description (#4567)`. We want to capture the middle part and use that in the + * release note. The `fix` part is optional, but occurs most of the time unless there + * is no issue associated. The `(#xxx)` part is also optional and much more rare, + * reflecting the PR number in case there has been extensive review/discussion in that + * PR. Both references would be caught by ISSUE_REF pattern below. + */ + static Pattern SHORT_MESSAGE = Pattern.compile("(?:[a-zA-Z]+ #[0-9]+)?([^\\(]+)(?:\\(#[0-9]+\\))?"); + + /** + * A {@link Pattern} to find issue/pr numbers in a commit message, by detecting + * {@code #}. + */ + protected static final Pattern ISSUE_REF = Pattern.compile("#([0-9]+)"); + + /** + * An enum of the 3 types of changes recognized by the changelog template, plus one + * type for noteworthy items (eg. breaking changes) and one additional type for the + * commits that couldn't be classified (eg. no relevant prefix and no associated + * issue). + */ + protected enum Type { + + NOTEWORTHY, BUG, FEATURE, DOC_MISC, UNCLASSIFIED; + + } + + /** + * Representation of an entry in the release notes changelog. + */ + protected static final class ChangelogEntry { + + /** + * The set of types of the change, or singleton {@link Type#UNCLASSIFIED} if + * unknown. + */ + public final EnumSet types; + + /** + * The human-friendly description to put in the release note for that commit. + */ + public final String description; + + /** + * The human-friendly SHA1 (typically abbreviated to 8 chars) to reference the + * commit in the release note if there is no associated issue. + */ + public final String commitSha1; + + /** + * An ordered map of github-compatible issue links (including the pound sign) and + * their titles, to be added to the draft as possible alternative descriptions. + * The links are automatically added to the end of the {@link #description} by the + * {@link #ChangelogEntry(EnumSet, String, String, Map)} constructor}. + */ + public final Map associatedIssueLinksAndTitles; + + /** + * @param types the set of {@link Type} of the commit + * @param commitSha1 the commit's human-friendly sha1 (can and should be the + * abbreviated form) + * @param cleanShortMessage the commit's cleaned up title, as should be displayed + * in the release note entry + * @param associatedIssueLinksAndTitles the commit's associated + * issue(s)/pull-request(s), in order of importance. If non-empty, each issue will + * be mentioned at the end of the entry, and the issue titles will be added to the + * {@link #description} on their own lines as potential alternative descriptions + */ + ChangelogEntry(EnumSet types, String commitSha1, String cleanShortMessage, + Map associatedIssueLinksAndTitles) { + this.types = types; + this.commitSha1 = commitSha1; + this.associatedIssueLinksAndTitles = associatedIssueLinksAndTitles; + + if (this.associatedIssueLinksAndTitles.isEmpty()) { + description = cleanShortMessage + " (" + commitSha1 + ")"; + } + else { + this.description = cleanShortMessage + " (" + + String.join(", ", this.associatedIssueLinksAndTitles.keySet()) + ")"; + } + } + + public String toString() { + return this.description; + } + + } + +} diff --git a/projects/reactor/src/main/java/releaser/reactor/ReactorConfiguration.java b/projects/reactor/src/main/java/releaser/reactor/ReactorConfiguration.java new file mode 100644 index 00000000..f6d68fee --- /dev/null +++ b/projects/reactor/src/main/java/releaser/reactor/ReactorConfiguration.java @@ -0,0 +1,65 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import com.jcabi.github.Github; +import com.jcabi.github.RtGithub; +import com.jcabi.http.wire.RetryWire; +import org.cloudfoundry.operations.CloudFoundryOperations; +import releaser.internal.Releaser; +import releaser.internal.ReleaserProperties; +import releaser.internal.git.ProjectGitHandler; + +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.util.StringUtils; + +@Configuration +@Profile("production") +class ReactorConfiguration { + + @Bean + CfClient cfClient(CloudFoundryOperations cloudFoundryOperations) { + return new CfClient(cloudFoundryOperations); + } + + @Bean + RestartSiteProjectPostReleaseTask restartSiteProjectPostReleaseTask(Releaser releaser, CfClient cfClient, + @Value("${cf.reactorAppName}") String reactorAppName) { + return new RestartSiteProjectPostReleaseTask(releaser, cfClient, reactorAppName); + } + + @Bean + Github githubClient(ReleaserProperties properties) { + if (!StringUtils.hasText(properties.getGit().getOauthToken())) { + throw new BeanInitializationException("You must set the value of the OAuth token. You can do it " + + "either via the command line [--releaser.git.oauth-token=...] " + + "or put it as an env variable in [~/.bashrc] or " + + "[~/.zshrc] e.g. [export RELEASER_GIT_OAUTH_TOKEN=...]"); + } + return new RtGithub(new RtGithub(properties.getGit().getOauthToken()).entry().through(RetryWire.class)); + } + + @Bean + GenerateReleaseNotesTask releaseNotesTask(Github github, ProjectGitHandler gitHandler) { + return new GenerateReleaseNotesTask(github, gitHandler); + } + +} diff --git a/projects/reactor/src/main/java/releaser/reactor/RestartSiteProjectPostReleaseTask.java b/projects/reactor/src/main/java/releaser/reactor/RestartSiteProjectPostReleaseTask.java new file mode 100644 index 00000000..8fcc4cc3 --- /dev/null +++ b/projects/reactor/src/main/java/releaser/reactor/RestartSiteProjectPostReleaseTask.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import org.cloudfoundry.operations.CloudFoundryOperations; +import org.cloudfoundry.operations.applications.RestartApplicationRequest; +import releaser.internal.Releaser; +import releaser.internal.spring.Arguments; +import releaser.internal.tasks.release.PublishDocsReleaseTask; +import releaser.internal.tech.ExecutionResult; + +public class RestartSiteProjectPostReleaseTask extends PublishDocsReleaseTask { + + private static final String REACTOR_CORE_PROJECT_NAME = "reactor-core"; + + private final CfClient cfClient; + + private final String reactorAppName; + + public RestartSiteProjectPostReleaseTask(Releaser releaser, CfClient cfClient, String reactorAppName) { + super(releaser); + this.cfClient = cfClient; + this.reactorAppName = reactorAppName; + } + + @Override + public ExecutionResult runTask(Arguments args) { + if (!REACTOR_CORE_PROJECT_NAME.equals(args.projectToRun.name())) { + return ExecutionResult.success(); + } + this.cfClient.restartApp(this.reactorAppName); + return ExecutionResult.success(); + } + +} + +class CfClient { + + private final CloudFoundryOperations cloudFoundryOperations; + + CfClient(CloudFoundryOperations cloudFoundryOperations) { + this.cloudFoundryOperations = cloudFoundryOperations; + } + + void restartApp(String name) { + this.cloudFoundryOperations.applications().restart(RestartApplicationRequest.builder().name(name).build()); + } + +} diff --git a/projects/reactor/src/main/resources/application.yml b/projects/reactor/src/main/resources/application.yml new file mode 100644 index 00000000..ee597ebb --- /dev/null +++ b/projects/reactor/src/main/resources/application.yml @@ -0,0 +1,38 @@ +spring: + main: + web-application-type: none + datasource: + url: jdbc:h2:mem:${random.uuid} + jackson: + deserialization: + FAIL_ON_UNKNOWN_PROPERTIES: true + profiles: + active: production +releaser: + git: + org-name: reactor + release-train-bom-url: https://github.com/reactor/reactor + fetch-versions-from-git: true + gradle: + build-command: "./gradlew clean bumpVersionsInReadme build publishToMavenLocal --console=plain -PnextVersion={{nextVersion}} -PoldVersion={{oldVersion}} -PcurrentVersion={{version}} {{systemProps}}" + + meta-release: + release-train-project-name: reactor + release-train-dependency-names: + - reactor + git-org-url: https://github.com/reactor +cf: + organization: FrameworksAndRuntimes + space: Reactor + reactorAppName: projectreactor + apiHost: api.run.pivotal.io + +# Boot values to be passed via env/command line: +# cf.username +# cf.password + +# Gradle project properties to be passed to deploy task somehow +# artifactory_publish_contextUrl +# artifactory_publish_repoKey +# artifactory_publish_username +# artifactory_publish_password \ No newline at end of file diff --git a/projects/reactor/src/main/resources/logback.xml b/projects/reactor/src/main/resources/logback.xml new file mode 100644 index 00000000..5aeeeb01 --- /dev/null +++ b/projects/reactor/src/main/resources/logback.xml @@ -0,0 +1,46 @@ + + + + + + + + + logs/reactor-releaser-commands.log + + + logs/reactor-releaser-commands.%i.log + 1 + 3 + + + 5MB + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + diff --git a/projects/reactor/src/test/java/releaser/ReleaserApplicationTests.java b/projects/reactor/src/test/java/releaser/ReleaserApplicationTests.java new file mode 100644 index 00000000..2243e494 --- /dev/null +++ b/projects/reactor/src/test/java/releaser/ReleaserApplicationTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Test; +import releaser.internal.tasks.DryRunReleaseReleaserTask; +import releaser.internal.tasks.ReleaserTask; +import releaser.internal.tasks.release.PublishDocsReleaseTask; +import releaser.reactor.GenerateReleaseNotesTask; +import releaser.reactor.RestartSiteProjectPostReleaseTask; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = { ReleaserApplication.class }) +@ActiveProfiles("test") +class ReleaserApplicationTests { + + @Autowired + ApplicationContext context; + + @Test + void contextLoads() { + + } + + @Test + void should_load_generate_release_notes_in_dry_run() { + Map beans = context.getBeansOfType(DryRunReleaseReleaserTask.class); + List inOrder = new LinkedList<>(beans.values()); + inOrder.sort(AnnotationAwareOrderComparator.INSTANCE); + + assertThat(inOrder).anySatisfy(task -> assertThat(task).isInstanceOf(GenerateReleaseNotesTask.class)); + } + + @Test + void should_load_restart_site() { + Map beans = context.getBeansOfType(ReleaserTask.class); + List inOrder = new LinkedList<>(beans.values()); + inOrder.sort(AnnotationAwareOrderComparator.INSTANCE); + + assertThat(inOrder).anySatisfy(task -> assertThat(task).isInstanceOf(RestartSiteProjectPostReleaseTask.class)); + assertThat(inOrder).noneSatisfy(task -> assertThat(task).isInstanceOf(PublishDocsReleaseTask.class) + .isNotInstanceOf(RestartSiteProjectPostReleaseTask.class)); + + } + +} diff --git a/projects/reactor/src/test/java/releaser/reactor/CfTestConfiguration.java b/projects/reactor/src/test/java/releaser/reactor/CfTestConfiguration.java new file mode 100644 index 00000000..35633bcb --- /dev/null +++ b/projects/reactor/src/test/java/releaser/reactor/CfTestConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import org.cloudfoundry.operations.CloudFoundryOperations; +import org.mockito.BDDMockito; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +/** + * @author Simon Baslé + */ +@Configuration +@Profile("test") +class CfTestConfiguration { + + @Bean + CloudFoundryOperations mockCloudFoundryOperations() { + return BDDMockito.mock(CloudFoundryOperations.class); + } + +} diff --git a/projects/reactor/src/test/java/releaser/reactor/GenerateReleaseNotesTaskTest.java b/projects/reactor/src/test/java/releaser/reactor/GenerateReleaseNotesTaskTest.java new file mode 100644 index 00000000..352d8320 --- /dev/null +++ b/projects/reactor/src/test/java/releaser/reactor/GenerateReleaseNotesTaskTest.java @@ -0,0 +1,275 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import com.jcabi.github.Issue; +import com.jcabi.github.Issues; +import com.jcabi.github.mock.MkGithub; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.mockito.stubbing.VoidAnswer4; +import releaser.internal.git.SimpleCommit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.AdditionalAnswers.answerVoid; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static releaser.reactor.GenerateReleaseNotesTask.Type; + +/** + * @author Simon Baslé + */ +@SpringBootTest +@ActiveProfiles("test") +class GenerateReleaseNotesTaskTest { + + @Autowired + GenerateReleaseNotesTask task; + + @Autowired + MkGithub githubClient; + + @Test + void extractTypeFromLabel() { + assertThat(task.extractTypes(Collections.singleton("type/bug"), "")).as("type/bug").containsOnly(Type.BUG); + + assertThat(task.extractTypes(Collections.singleton("type/enhancement"), "")).as("type/enhancement") + .containsOnly(Type.FEATURE); + + assertThat(task.extractTypes(Collections.singleton("type/documentation"), "")).as("type/documentation") + .containsOnly(Type.DOC_MISC); + + assertThat(task.extractTypes(Collections.singleton("type/chores"), "")).as("type/chores") + .containsOnly(Type.DOC_MISC); + + assertThat(task.extractTypes(Collections.singleton("warn/something"), "")).as("warn/*") + .containsOnly(Type.NOTEWORTHY); + + assertThat(task.extractTypes(Collections.singleton("type/whatever"), "")).as("type/whatever") + .containsOnly(Type.UNCLASSIFIED); + } + + @Test + void extractTypeFromMultipleLabels() { + Set labels = new LinkedHashSet<>(); + labels.add("type/bug"); + labels.add("type/enhancement"); + labels.add("type/documentation"); + labels.add("whatever"); + + assertThat(task.extractTypes(labels, "")).as("multiple labels").containsOnly(Type.BUG, Type.FEATURE, + Type.DOC_MISC); + } + + @Test + void extractMiscTypeFromBuildMessagePrefix() { + String message = "[build] Foo"; + + assertThat(task.extractTypes(Collections.emptySet(), message)).containsOnly(Type.DOC_MISC); + } + + @Test + void extractMiscTypeFromPolishMessagePrefix() { + String message = "[polish] Foo"; + + assertThat(task.extractTypes(Collections.emptySet(), message)).containsOnly(Type.DOC_MISC); + } + + @Test + void extractMiscTypeFromDocMessagePrefix() { + String message = "[doc] Foo"; + + assertThat(task.extractTypes(Collections.emptySet(), message)).containsOnly(Type.DOC_MISC); + } + + @Test + void extractUnclassifiedTypeFromRandomMessagePrefix() { + String message = "fix #123 There was a [bug], needed to [polish] the [doc]"; + + assertThat(task.extractTypes(Collections.emptySet(), message)).containsOnly(Type.UNCLASSIFIED); + } + + @Test + void noTitleCleanupFromMergeCommit() { + SimpleCommit mergeCommit = new SimpleCommit("sha1", "fullsha1", "merge #123 into 3.3 (#123)", + "merge #123 into 3.3", "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", true); + + assertThat(task.cleanupShortMessage(mergeCommit)).isEqualTo("merge #123 into 3.3 (#123)"); + } + + @Test + void titleCleanupFixPrefix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "fix #123 Text from title", + "fix #123 Some more text", "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", + false); + + assertThat(task.cleanupShortMessage(commit)).isEqualTo("Text from title"); + } + + @Test + void titleCleanupSeePrefix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "see #123 Text from title", + "see #123 Some more text", "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", + false); + + assertThat(task.cleanupShortMessage(commit)).isEqualTo("Text from title"); + } + + @Test + void titleCleanupPrStyleSuffix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "Commit without issue (#123)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.cleanupShortMessage(commit)).isEqualTo("Commit without issue"); + } + + @Test + void titleCleanupPrStyleSuffixNoSpace() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "Commit without issue(#123)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.cleanupShortMessage(commit)).isEqualTo("Commit without issue"); + } + + @Test + void titleCleanupBothPrefixAndSuffix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123 Commit title (#123)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.cleanupShortMessage(commit)).isEqualTo("Commit title"); + } + + @Test + void issueNumberTitlePrefix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123 Commit title", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.extractIssueNumbers(commit)).containsOnly(123); + } + + @Test + void issueNumberTitlePrStyleSuffix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "Commit title (#123)", "fullMessage", "Simon Baslé", + "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.extractIssueNumbers(commit)).containsOnly(123); + } + + @Test + void issueNumberTitlePrefixAndSuffix() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123 Commit title (#456)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.extractIssueNumbers(commit)).containsOnly(123, 456); + } + + @Test + void issueNumberTitleNotSeparatedBySpace() { + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix#123Commit title(#456)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(task.extractIssueNumbers(commit)).containsOnly(123, 456); + } + + static final VoidAnswer4, Set, Map> MOCK_FETCH_ISSUES = (ignore1, + issues, ignore2, resolved) -> issues.forEach(i -> resolved.put("#" + i, "alternative title for " + i)); + + static final Issues MOCK_ISSUES = Mockito.mock(Issues.class); + + @Test + void generateChangelogDescriptionSingleIssueTwice() throws IOException { + final GenerateReleaseNotesTask spy = Mockito.spy(task); + doAnswer(answerVoid(MOCK_FETCH_ISSUES)).when(spy).fetchIssueLabelsAndTitles(any(), any(), any(), any()); + + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123 Commit title (#123)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(spy.parseChangeLogEntry(githubClient.randomRepo().issues(), commit).description) + .isEqualTo("Commit title (#123)"); + } + + @Test + void generateChangelogDescriptionTwoIssues() throws IOException { + final GenerateReleaseNotesTask spy = Mockito.spy(task); + doAnswer(answerVoid(MOCK_FETCH_ISSUES)).when(spy).fetchIssueLabelsAndTitles(any(), any(), any(), any()); + + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123 Commit title (#456)", "fullMessage", + "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(spy.parseChangeLogEntry(MOCK_ISSUES, commit).description).isEqualTo("Commit title (#123, #456)"); + } + + @Test + void generateChangelogDescriptionTwoIssuesNoSpace() throws IOException { + final GenerateReleaseNotesTask spy = Mockito.spy(task); + doAnswer(answerVoid(MOCK_FETCH_ISSUES)).when(spy).fetchIssueLabelsAndTitles(any(), any(), any(), any()); + + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123Commit title no space(#456)", + "fullMessage", "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(spy.parseChangeLogEntry(githubClient.randomRepo().issues(), commit).description) + .isEqualTo("Commit title no space (#123, #456)"); + } + + @Test + void generateChangelogDescriptionNoMatchingIssueUsesShortSha1() throws IOException { + final GenerateReleaseNotesTask spy = Mockito.spy(task); + doNothing().when(spy).fetchIssueLabelsAndTitles(any(), any(), any(), any()); + + SimpleCommit commit = new SimpleCommit("sha1", "fullsha1", "prefix #123 Commit title no space(#456)", + "fullMessage", "Simon Baslé", "sbasle@pivotal.io", "Simon Baslé", "sbasle@pivotal.io", false); + + assertThat(spy.parseChangeLogEntry(githubClient.randomRepo().issues(), commit).description) + .isEqualTo("Commit title no space (sha1)"); + } + + @Test + void issueInfoFetchProtectedWhenIssueNotFound() throws IOException { + Issues issuesClient = githubClient.randomRepo().issues(); + Set labels = new HashSet<>(); + Map associatedIssues = new HashMap<>(); + + assertThatExceptionOfType(Exception.class).as("github client fails") + .isThrownBy(() -> new Issue.Smart(issuesClient.get(123)).title()); + + assertThatCode(() -> task.fetchIssueLabelsAndTitles(issuesClient, Collections.singleton(123), labels, + associatedIssues)).as("fetching just does nothing").doesNotThrowAnyException(); + + assertThat(labels).as("labels").isEmpty(); + assertThat(associatedIssues).as("associated issues").isEmpty(); + } + + // TODO test login extraction by mocking the task's commitToGithubMention method + + // TODO find a way to mock commits and thus test extractContributors + +} diff --git a/projects/reactor/src/test/java/releaser/reactor/ReactorTestConfiguration.java b/projects/reactor/src/test/java/releaser/reactor/ReactorTestConfiguration.java new file mode 100644 index 00000000..e0afcd95 --- /dev/null +++ b/projects/reactor/src/test/java/releaser/reactor/ReactorTestConfiguration.java @@ -0,0 +1,97 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import java.io.IOException; + +import com.jcabi.github.Github; +import com.jcabi.github.mock.MkGithub; +import org.mockito.BDDMockito; +import org.mockito.Mockito; +import releaser.internal.Releaser; +import releaser.internal.git.ProjectGitHandler; +import releaser.internal.options.Parser; +import releaser.internal.spring.ExecutionResultHandler; +import releaser.internal.spring.SpringReleaser; + +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; + +/** + * A configuration for tests, that mocks external clients but reuses the base bean + * declaration for tasks. + * + * @author Simon Baslé + */ +@Configuration +@Profile("test") +public class ReactorTestConfiguration { + + @Bean + RestartSiteProjectPostReleaseTask restartSiteProjectPostReleaseTask(Releaser releaser, CfClient cfClient, + @Value("${cf.reactorAppName}") String reactorAppName) { + return new RestartSiteProjectPostReleaseTask(releaser, cfClient, reactorAppName); + } + + @Bean + GenerateReleaseNotesTask releaseNotesTask(Github github, ProjectGitHandler gitHandler) { + return new GenerateReleaseNotesTask(github, gitHandler); + } + + @Bean + ProjectGitHandler mockGitHandler() { + return Mockito.mock(ProjectGitHandler.class); + } + + @Bean + MkGithub mockGithub() { + try { + return new MkGithub(); + } + catch (IOException e) { + throw new BeanCreationException("Unable to create mock Github bean", e); + } + } + + @Bean + CfClient mockCfClient() { + return BDDMockito.mock(CfClient.class); + } + + @Bean + @Primary + SpringReleaser mockReleaser() { + return Mockito.mock(SpringReleaser.class); + } + + @Bean + @Primary + ExecutionResultHandler mockExecutionResultHandler() { + return Mockito.mock(ExecutionResultHandler.class); + } + + @Bean + @Primary + Parser mockParser() { + return Mockito.mock(Parser.class); + } + +} diff --git a/projects/reactor/src/test/java/releaser/reactor/RestartSiteProjectPostReleaseTaskTests.java b/projects/reactor/src/test/java/releaser/reactor/RestartSiteProjectPostReleaseTaskTests.java new file mode 100644 index 00000000..099ef13f --- /dev/null +++ b/projects/reactor/src/test/java/releaser/reactor/RestartSiteProjectPostReleaseTaskTests.java @@ -0,0 +1,105 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.reactor; + +import org.assertj.core.api.BDDAssertions; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import releaser.internal.ReleaserProperties; +import releaser.internal.options.Options; +import releaser.internal.project.ProjectVersion; +import releaser.internal.project.Projects; +import releaser.internal.spring.Arguments; +import releaser.internal.spring.ProjectToRun; +import releaser.internal.spring.ProjectsFromBom; +import releaser.internal.tech.ExecutionResult; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import static org.junit.jupiter.api.Assertions.fail; + +@SpringBootTest +@ActiveProfiles("test") +class RestartSiteProjectPostReleaseTaskTests { + + @Autowired + RestartSiteProjectPostReleaseTask task; + + @Autowired + CfClient cfClient; + + @Test + void should_update_the_website() { + Arguments arguments = Arguments.forProject(reactorCoreProject()); + + ExecutionResult result = task.runTask(arguments); + + BDDAssertions.then(result.isSuccess()).isTrue(); + BDDMockito.then(this.cfClient).should().restartApp(BDDMockito.eq("projectreactor")); + } + + @Test + void should_fail_if_original_version_is_null() { + ProjectToRun p = new ProjectToRun(null, new ProjectsFromBom(new Projects(), new ProjectVersion("foo", "1.0.0")), + null, new ReleaserProperties(), BDDMockito.mock(Options.class)) { + @Override + public String name() { + return "reactor-core"; + } + }; + try { + Arguments.forProject(p); + fail(); + } + catch (Exception e) { + // success + } + } + + @Test + void should_not_update_the_website_if_project_not_reactor_core() { + Arguments arguments = Arguments.forProject(nonReactorCoreProject()); + + ExecutionResult result = task.runTask(arguments); + + BDDAssertions.then(result.isSuccess()).isTrue(); + BDDMockito.then(this.cfClient).shouldHaveNoInteractions(); + } + + private ProjectToRun reactorCoreProject() { + return new ProjectToRun(null, new ProjectsFromBom(new Projects(), new ProjectVersion("foo", "1.0.0")), + new ProjectVersion("foo", "1.0.0"), new ReleaserProperties(), BDDMockito.mock(Options.class)) { + @Override + public String name() { + return "reactor-core"; + } + }; + } + + private ProjectToRun nonReactorCoreProject() { + return new ProjectToRun(null, new ProjectsFromBom(new Projects(), new ProjectVersion("foo", "1.0.0")), + new ProjectVersion("foo", "1.0.0"), new ReleaserProperties(), BDDMockito.mock(Options.class)) { + @Override + public String name() { + return "whatever"; + } + }; + } + +} diff --git a/projects/reactor/src/test/resources/application-test.yml b/projects/reactor/src/test/resources/application-test.yml new file mode 100644 index 00000000..79678c85 --- /dev/null +++ b/projects/reactor/src/test/resources/application-test.yml @@ -0,0 +1,3 @@ +cf: + username: foo + password: bar \ No newline at end of file diff --git a/projects/spring-cloud-stream/pom.xml b/projects/spring-cloud-stream/pom.xml index ac0baaf0..c708127c 100644 --- a/projects/spring-cloud-stream/pom.xml +++ b/projects/spring-cloud-stream/pom.xml @@ -10,13 +10,13 @@ org.springframework.cloud.internal releaser-projects - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT .. UTF-8 - 17 + 1.8 diff --git a/projects/spring-cloud-stream/src/main/java/releaser/cloud/buildsystem/SpringCloudStreamMavenBomParser.java b/projects/spring-cloud-stream/src/main/java/releaser/cloud/buildsystem/SpringCloudStreamMavenBomParser.java index 27756e44..6b42e6c9 100644 --- a/projects/spring-cloud-stream/src/main/java/releaser/cloud/buildsystem/SpringCloudStreamMavenBomParser.java +++ b/projects/spring-cloud-stream/src/main/java/releaser/cloud/buildsystem/SpringCloudStreamMavenBomParser.java @@ -138,30 +138,30 @@ class SpringCloudStreamMavenBomParser implements CustomBomParser { public Set setVersion(Set projects, String projectName, String version) { Set newProjects = new LinkedHashSet<>(projects); switch (projectName) { - case SPRING_BOOT: - case BOOT_STARTER_ARTIFACT_ID: - case BOOT_STARTER_PARENT_ARTIFACT_ID: - case BOOT_DEPENDENCIES_ARTIFACT_ID: - updateBootVersions(newProjects, version); - break; - case BUILD_ARTIFACT_ID: - case CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID: - updateBuildVersions(newProjects, version); - break; - case CLOUD_ARTIFACT_ID: - case CLOUD_DEPENDENCIES_ARTIFACT_ID: - case CLOUD_RELEASE_ARTIFACT_ID: - case CLOUD_STARTER_ARTIFACT_ID: - case CLOUD_STARTER_PARENT_ARTIFACT_ID: - updateSpringCloudVersions(newProjects, version); - break; - case STREAM_DEPS_ARTIFACT_ID: - case STREAM_STARTER_ARTIFACT_ID: - case STREAM_STARTER_BUILD_ARTIFACT_ID: - case STREAM_STARTER_PARENT_ARTIFACT_ID: - case STREAM_DOCS_ARTIFACT_ID: - updateStreamVersions(newProjects, version); - break; + case SPRING_BOOT: + case BOOT_STARTER_ARTIFACT_ID: + case BOOT_STARTER_PARENT_ARTIFACT_ID: + case BOOT_DEPENDENCIES_ARTIFACT_ID: + updateBootVersions(newProjects, version); + break; + case BUILD_ARTIFACT_ID: + case CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID: + updateBuildVersions(newProjects, version); + break; + case CLOUD_ARTIFACT_ID: + case CLOUD_DEPENDENCIES_ARTIFACT_ID: + case CLOUD_RELEASE_ARTIFACT_ID: + case CLOUD_STARTER_ARTIFACT_ID: + case CLOUD_STARTER_PARENT_ARTIFACT_ID: + updateSpringCloudVersions(newProjects, version); + break; + case STREAM_DEPS_ARTIFACT_ID: + case STREAM_STARTER_ARTIFACT_ID: + case STREAM_STARTER_BUILD_ARTIFACT_ID: + case STREAM_STARTER_PARENT_ARTIFACT_ID: + case STREAM_DOCS_ARTIFACT_ID: + updateStreamVersions(newProjects, version); + break; } return newProjects; } diff --git a/projects/spring-cloud/pom.xml b/projects/spring-cloud/pom.xml index 910c3b3a..30071afd 100644 --- a/projects/spring-cloud/pom.xml +++ b/projects/spring-cloud/pom.xml @@ -10,13 +10,13 @@ org.springframework.cloud.internal releaser-projects - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT .. UTF-8 - 17 + 1.8 diff --git a/projects/spring-cloud/src/main/java/releaser/cloud/buildsystem/SpringCloudMavenBomParser.java b/projects/spring-cloud/src/main/java/releaser/cloud/buildsystem/SpringCloudMavenBomParser.java index 349704ca..48c9af0d 100644 --- a/projects/spring-cloud/src/main/java/releaser/cloud/buildsystem/SpringCloudMavenBomParser.java +++ b/projects/spring-cloud/src/main/java/releaser/cloud/buildsystem/SpringCloudMavenBomParser.java @@ -139,31 +139,31 @@ class SpringCloudMavenBomParser implements CustomBomParser { public Set setVersion(Set projects, String projectName, String version) { Set newProjects = new LinkedHashSet<>(projects); switch (projectName) { - case SPRING_BOOT: - case BOOT_STARTER_ARTIFACT_ID: - case BOOT_STARTER_PARENT_ARTIFACT_ID: - case BOOT_DEPENDENCIES_ARTIFACT_ID: - updateBootVersions(newProjects, version); - break; - case BUILD_ARTIFACT_ID: - case CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID: - updateBuildVersions(newProjects, version); - break; - case CLOUD_ARTIFACT_ID: - case CLOUD_DEPENDENCIES_ARTIFACT_ID: - case CLOUD_RELEASE_ARTIFACT_ID: - case CLOUD_STARTER_ARTIFACT_ID: - case CLOUD_STARTER_PARENT_ARTIFACT_ID: - case CLOUD_STARTER_BUILD_ARTIFACT_ID: - updateSpringCloudVersions(newProjects, version); - break; - case STREAM_DEPS_ARTIFACT_ID: - case STREAM_STARTER_ARTIFACT_ID: - case STREAM_STARTER_BUILD_ARTIFACT_ID: - case STREAM_STARTER_PARENT_ARTIFACT_ID: - case STREAM_DOCS_ARTIFACT_ID: - updateStreamVersions(newProjects, version); - break; + case SPRING_BOOT: + case BOOT_STARTER_ARTIFACT_ID: + case BOOT_STARTER_PARENT_ARTIFACT_ID: + case BOOT_DEPENDENCIES_ARTIFACT_ID: + updateBootVersions(newProjects, version); + break; + case BUILD_ARTIFACT_ID: + case CLOUD_DEPENDENCIES_PARENT_ARTIFACT_ID: + updateBuildVersions(newProjects, version); + break; + case CLOUD_ARTIFACT_ID: + case CLOUD_DEPENDENCIES_ARTIFACT_ID: + case CLOUD_RELEASE_ARTIFACT_ID: + case CLOUD_STARTER_ARTIFACT_ID: + case CLOUD_STARTER_PARENT_ARTIFACT_ID: + case CLOUD_STARTER_BUILD_ARTIFACT_ID: + updateSpringCloudVersions(newProjects, version); + break; + case STREAM_DEPS_ARTIFACT_ID: + case STREAM_STARTER_ARTIFACT_ID: + case STREAM_STARTER_BUILD_ARTIFACT_ID: + case STREAM_STARTER_PARENT_ARTIFACT_ID: + case STREAM_DOCS_ARTIFACT_ID: + updateStreamVersions(newProjects, version); + break; } return newProjects; } diff --git a/projects/spring-cloud/src/main/java/releaser/cloud/github/SpringCloudGithubIssues.java b/projects/spring-cloud/src/main/java/releaser/cloud/github/SpringCloudGithubIssues.java index bf445e5a..76c0d99b 100644 --- a/projects/spring-cloud/src/main/java/releaser/cloud/github/SpringCloudGithubIssues.java +++ b/projects/spring-cloud/src/main/java/releaser/cloud/github/SpringCloudGithubIssues.java @@ -16,7 +16,7 @@ package releaser.cloud.github; -import org.kohsuke.github.GitHub; +import com.jcabi.github.Github; import releaser.internal.ReleaserProperties; import releaser.internal.github.CustomGithubIssues; import releaser.internal.github.GithubIssueFiler; @@ -38,41 +38,25 @@ class SpringCloudGithubIssues implements CustomGithubIssues { this.properties = properties; } - SpringCloudGithubIssues(GitHub github, ReleaserProperties properties) { + SpringCloudGithubIssues(Github github, ReleaserProperties properties) { this.githubIssueFiler = new GithubIssueFiler(github, properties); this.properties = properties; } @Override public void fileIssueInSpringGuides(Projects projects, ProjectVersion version) { - String user = getGuidesOrg(); - String repo = getGuidesRepo(); + String user = "spring-guides"; + String repo = "getting-started-guides"; this.githubIssueFiler.fileAGitHubIssue(user, repo, version, issueTitle(), guidesIssueText(projects)); } @Override public void fileIssueInStartSpringIo(Projects projects, ProjectVersion version) { - String user = getStartSpringIoOrg(); - String repo = getStartSpringIoRepo(); + String user = "spring-io"; + String repo = "start.spring.io"; this.githubIssueFiler.fileAGitHubIssue(user, repo, version, issueTitle(), startSpringIoIssueText(projects)); } - String getGuidesOrg() { - return "spring-guides"; - } - - String getGuidesRepo() { - return "getting-started-guides"; - } - - String getStartSpringIoOrg() { - return "spring-io"; - } - - String getStartSpringIoRepo() { - return "start.spring.io"; - } - private String issueTitle() { return String.format(GITHUB_ISSUE_TITLE, StringUtils.capitalize(parsedVersion())); } diff --git a/projects/spring-cloud/src/main/resources/application.yml b/projects/spring-cloud/src/main/resources/application.yml index 95d93d38..1e4b9383 100644 --- a/projects/spring-cloud/src/main/resources/application.yml +++ b/projects/spring-cloud/src/main/resources/application.yml @@ -41,6 +41,10 @@ releaser: update-release-train-wiki: true update-all-test-samples: true all-test-sample-urls: + spring-cloud-sleuth: + - https://github.com/spring-cloud-samples/sleuth-issues + - https://github.com/spring-cloud-samples/sleuth-documentation-apps + - https://github.com/spring-cloud-samples/spring-cloud-sleuth-samples spring-cloud-contract: - https://github.com/spring-cloud-samples/spring-cloud-contract-samples - https://github.com/spring-cloud-samples/the-legacy-app @@ -97,7 +101,7 @@ releaser: enabled: true template-folder: cloud versions: - all-versions-file-url: https://raw.githubusercontent.com/spring-io/start.spring.io/main/start-site/src/main/resources/application.yml + all-versions-file-url: https://raw.githubusercontent.com/spring-io/start.spring.io/master/start-site/src/main/resources/application.yml bom-name: spring-cloud # fixed-versions: meta-release: diff --git a/projects/spring-cloud/src/test/java/releaser/cloud/docs/SpringCloudCustomProjectDocumentationUpdaterTests.java b/projects/spring-cloud/src/test/java/releaser/cloud/docs/SpringCloudCustomProjectDocumentationUpdaterTests.java index c1e104ce..fd30854f 100644 --- a/projects/spring-cloud/src/test/java/releaser/cloud/docs/SpringCloudCustomProjectDocumentationUpdaterTests.java +++ b/projects/spring-cloud/src/test/java/releaser/cloud/docs/SpringCloudCustomProjectDocumentationUpdaterTests.java @@ -23,6 +23,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; +import javax.validation.constraints.NotNull; + import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -43,7 +45,7 @@ import org.springframework.util.FileSystemUtils; /** * @author Marcin Grzejszczak */ -class SpringCloudCustomProjectDocumentationUpdaterTests { +public class SpringCloudCustomProjectDocumentationUpdaterTests { File project; @@ -59,7 +61,7 @@ class SpringCloudCustomProjectDocumentationUpdaterTests { ReleaserProperties properties = SpringCloudReleaserProperties.get(); @BeforeEach - void setup() throws IOException, URISyntaxException { + public void setup() throws IOException, URISyntaxException { this.project = new File(SpringCloudCustomProjectDocumentationUpdater.class .getResource("/projects/spring-cloud-static").toURI()); TestUtils.prepareLocalRepo(); @@ -71,17 +73,19 @@ class SpringCloudCustomProjectDocumentationUpdaterTests { Collections.singletonList(SpringCloudGithubIssuesAccessor.springCloud(this.properties))); } + @NotNull private DocumentationUpdater projectDocumentationUpdater(ReleaserProperties properties) { return new DocumentationUpdater(this.handler, properties, templateGenerator(properties), Collections.singletonList(new SpringCloudCustomProjectDocumentationUpdater(this.handler, properties))); } + @NotNull private TemplateGenerator templateGenerator(ReleaserProperties properties) { return new TemplateGenerator(properties, this.gitHubHandler); } @Test - void should_not_update_current_version_in_the_docs_if_current_release_starts_with_v_and_then_lower_letter_than_the_stored_release() + public void should_not_update_current_version_in_the_docs_if_current_release_starts_with_v_and_then_lower_letter_than_the_stored_release() throws URISyntaxException, IOException { ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-release", "Finchley.SR33"); ReleaserProperties properties = new ReleaserProperties(); @@ -110,7 +114,7 @@ class SpringCloudCustomProjectDocumentationUpdaterTests { } @Test - void should_not_commit_if_the_same_version_is_already_there() { + public void should_not_commit_if_the_same_version_is_already_there() { ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-release", "Dalston.SR3"); ReleaserProperties properties = new ReleaserProperties(); properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString()); @@ -123,7 +127,7 @@ class SpringCloudCustomProjectDocumentationUpdaterTests { } @Test - void should_do_nothing_when_release_train_docs_update_happen_for_a_project_that_does_not_start_with_spring_cloud() { + public void should_do_nothing_when_release_train_docs_update_happen_for_a_project_that_does_not_start_with_spring_cloud() { ProjectVersion springBootVersion = new ProjectVersion("spring-boot", "2.2.5"); ReleaserProperties properties = new ReleaserProperties(); properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString()); @@ -136,7 +140,7 @@ class SpringCloudCustomProjectDocumentationUpdaterTests { } @Test - void should_do_nothing_when_single_project_docs_update_happen_for_a_project_that_does_not_start_with_spring_cloud() { + public void should_do_nothing_when_single_project_docs_update_happen_for_a_project_that_does_not_start_with_spring_cloud() { ProjectVersion springBootVersion = new ProjectVersion("spring-boot", "2.2.5"); ReleaserProperties properties = new ReleaserProperties(); properties.getGit().setDocumentationUrl(this.clonedDocProject.toURI().toString()); @@ -149,7 +153,7 @@ class SpringCloudCustomProjectDocumentationUpdaterTests { } @Test - void should_not_update_current_version_in_the_docs_if_current_release_starts_with_lower_letter_than_the_stored_release() + public void should_not_update_current_version_in_the_docs_if_current_release_starts_with_lower_letter_than_the_stored_release() throws IOException { ProjectVersion releaseTrainVersion = new ProjectVersion("spring-cloud-release", "Angel.SR33"); ReleaserProperties properties = new ReleaserProperties(); diff --git a/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesAccessor.java b/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesAccessor.java index 98cd35a8..d8e9c03c 100644 --- a/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesAccessor.java +++ b/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesAccessor.java @@ -16,13 +16,13 @@ package releaser.cloud.github; -import org.kohsuke.github.GitHub; +import com.jcabi.github.Github; import releaser.internal.ReleaserProperties; import releaser.internal.github.CustomGithubIssues; public class SpringCloudGithubIssuesAccessor { - public static CustomGithubIssues springCloud(GitHub github, ReleaserProperties releaserProperties) { + public static CustomGithubIssues springCloud(Github github, ReleaserProperties releaserProperties) { return new SpringCloudGithubIssues(github, releaserProperties); } diff --git a/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesTests.java b/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesTests.java new file mode 100644 index 00000000..763cebcc --- /dev/null +++ b/projects/spring-cloud/src/test/java/releaser/cloud/github/SpringCloudGithubIssuesTests.java @@ -0,0 +1,179 @@ +/* + * Copyright 2013-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package releaser.cloud.github; + +import java.io.IOException; +import java.util.Collections; + +import com.jcabi.github.Coordinates; +import com.jcabi.github.Github; +import com.jcabi.github.Issue; +import com.jcabi.github.Repo; +import com.jcabi.github.Repos; +import com.jcabi.github.mock.MkGithub; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.BDDMockito; +import releaser.cloud.SpringCloudReleaserProperties; +import releaser.internal.ReleaserProperties; +import releaser.internal.github.CustomGithubIssues; +import releaser.internal.project.ProjectVersion; +import releaser.internal.project.Projects; + +import static org.assertj.core.api.BDDAssertions.then; +import static org.assertj.core.api.BDDAssertions.thenThrownBy; + +/** + * @author Marcin Grzejszczak + */ +public class SpringCloudGithubIssuesTests { + + ReleaserProperties properties = SpringCloudReleaserProperties.get(); + + MkGithub github; + + Repo repo; + + @BeforeEach + public void setup() throws IOException { + this.github = github("spring-guides"); + this.properties.getGit().setOauthToken("a"); + this.repo = createGettingStartedGuides(this.github); + } + + public void setupStartSpringIo() throws IOException { + this.github = github("spring-io"); + this.repo = createStartSpringIo(this.github); + } + + private MkGithub github(String login) throws IOException { + return new MkGithub(login); + } + + @Test + public void should_not_do_anything_for_non_release_train_version() { + Github github = BDDMockito.mock(Github.class); + CustomGithubIssues githubIssues = new SpringCloudGithubIssues(github, properties); + + githubIssues.fileIssueInSpringGuides( + new Projects(new ProjectVersion("foo", "1.0.0.BUILD-SNAPSHOT"), + new ProjectVersion("spring-cloud-build", "2.0.0.BUILD-SNAPSHOT")), + new ProjectVersion("sc-release", "Edgware.BUILD-SNAPSHOT")); + + BDDMockito.then(github).shouldHaveNoInteractions(); + } + + @Test + public void should_file_an_issue_for_release_version() throws IOException { + CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties); + properties.getPom().setBranch("vEdgware.RELEASE"); + + issues.fileIssueInSpringGuides( + new Projects(new ProjectVersion("spring-cloud-foo", "1.0.0.RELEASE"), + new ProjectVersion("spring-cloud-build", "2.0.0.RELEASE"), + new ProjectVersion("bar", "2.0.0.RELEASE"), new ProjectVersion("baz", "3.0.0.RELEASE")), + new ProjectVersion("sc-release", "Edgware.RELEASE")); + + Issue issue = this.github.repos().get(new Coordinates.Simple("spring-guides", "getting-started-guides")) + .issues().get(1); + then(issue.exists()).isTrue(); + Issue.Smart smartIssue = new Issue.Smart(issue); + then(smartIssue.title()).isEqualTo("Upgrade to Spring Cloud Edgware.RELEASE"); + then(smartIssue.body()).contains( + "Release train [spring-cloud-release] in version [Edgware.RELEASE] released with the following projects") + .contains("spring-cloud-foo : `1.0.0.RELEASE`").contains("bar : `2.0.0.RELEASE`") + .contains("baz : `3.0.0.RELEASE`"); + } + + @Test + public void should_throw_exception_when_no_token_was_passed() { + properties.getGit().setOauthToken(""); + CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties); + + thenThrownBy(() -> issues.fileIssueInSpringGuides( + new Projects(Collections.singletonList(new ProjectVersion("spring-cloud-build", "2.0.0.RELEASE"))), + nonGaSleuthProject())).isInstanceOf(IllegalArgumentException.class).hasMessageContaining( + "You have to pass Github OAuth token for milestone closing to be operational"); + } + + @Test + public void should_not_do_anything_for_non_release_train_version_when_updating_startspringio() throws IOException { + setupStartSpringIo(); + Github github = BDDMockito.mock(Github.class); + CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties); + + issues.fileIssueInStartSpringIo( + new Projects(new ProjectVersion("foo", "1.0.0.BUILD-SNAPSHOT"), + new ProjectVersion("spring-cloud-build", "2.0.0.RELEASE")), + new ProjectVersion("sc-release", "Edgware.BUILD-SNAPSHOT")); + + BDDMockito.then(github).shouldHaveNoInteractions(); + } + + @Test + public void should_file_an_issue_for_release_version_when_updating_startspringio() throws IOException { + setupStartSpringIo(); + CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties); + properties.getPom().setBranch("vEdgware.RELEASE"); + + issues.fileIssueInStartSpringIo(new Projects(new ProjectVersion("spring-cloud-foo", "1.0.0.RELEASE"), + new ProjectVersion("spring-cloud-build", "2.0.0.RELEASE"), new ProjectVersion("bar", "2.0.0.RELEASE"), + new ProjectVersion("baz", "3.0.0.RELEASE"), new ProjectVersion("spring-boot", "1.2.3.RELEASE")), + new ProjectVersion("sc-release", "Edgware.RELEASE")); + + Issue issue = this.github.repos().get(new Coordinates.Simple("spring-io", "start.spring.io")).issues().get(1); + then(issue.exists()).isTrue(); + Issue.Smart smartIssue = new Issue.Smart(issue); + then(smartIssue.title()).isEqualTo("Upgrade to Spring Cloud Edgware.RELEASE"); + then(smartIssue.body()).contains( + "Release train [spring-cloud-release] in version [Edgware.RELEASE] released with the Spring Boot version [`1.2.3.RELEASE`]"); + } + + @Test + public void should_throw_exception_when_no_token_was_passed_when_updating_startspringio() throws IOException { + setupStartSpringIo(); + properties.getGit().setOauthToken(""); + CustomGithubIssues issues = new SpringCloudGithubIssues(github, properties); + + thenThrownBy(() -> issues.fileIssueInStartSpringIo( + new Projects(Collections.singletonList(new ProjectVersion("spring-cloud-build", "2.0.0.RELEASE"))), + nonGaSleuthProject())).isInstanceOf(IllegalArgumentException.class).hasMessageContaining( + "You have to pass Github OAuth token for milestone closing to be operational"); + } + + private Repo createGettingStartedGuides(MkGithub github) throws IOException { + return github.repos().create(new Repos.RepoCreate("getting-started-guides", false)); + } + + private Repo createStartSpringIo(MkGithub github) throws IOException { + return github.repos().create(new Repos.RepoCreate("start.spring.io", false)); + } + + private ProjectVersion nonGaSleuthProject() { + return new ProjectVersion("spring-cloud-sleuth", "0.2.0.BUILD-SNAPSHOT"); + } + + ReleaserProperties withToken() { + ReleaserProperties properties = SpringCloudReleaserProperties.get(); + properties.getGit().setOauthToken("foo"); + properties.getPom().setBranch("vEdgware.RELEASE"); + properties.getGit().setUpdateSpringGuides(true); + properties.getGit().setUpdateStartSpringIo(true); + return properties; + } + +} diff --git a/releaser-core/pom.xml b/releaser-core/pom.xml index 968d34e6..5e73edde 100644 --- a/releaser-core/pom.xml +++ b/releaser-core/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud.internal releaser-parent - 3.0.0-SNAPSHOT + 2.0.0-SNAPSHOT .. @@ -35,31 +35,40 @@ org.eclipse.jgit org.eclipse.jgit - - - org.eclipse.jgit - org.eclipse.jgit.ssh.jsch + ${org.eclipse.jgit-version} com.jcraft jsch.agentproxy.sshagent + ${jsch-agent.version} + + + org.eclipse.jgit + org.eclipse.jgit.ssh.jsch + ${org.eclipse.jgit-version} com.jcraft jsch.agentproxy.jsch + ${jsch-agent.version} com.jcraft jsch.agentproxy.usocket-jna + ${jsch-agent.version} org.apache.maven maven-model + + + ${maven-model.version} org.codehaus.mojo versions-maven-plugin + ${versions-maven-plugin.version} org.slf4j @@ -76,20 +85,19 @@ - org.kohsuke - github-api - - - com.squareup.okhttp3 - okhttp + com.jcabi + jcabi-github + ${jcabi-github.version} com.github.jknack handlebars + ${handlebars.version} io.spring.initializr initializr-metadata + ${initializr-metadata.version} org.springframework.boot @@ -104,6 +112,7 @@ org.awaitility awaitility + ${awaitility.version} test ",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("properties",function(r){var t="[ \\t\\f]*",e="[ \\t\\f]+",s="("+t+"[:=]"+t+"|"+e+")",n="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",c={e:s,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[r.C("^\\s*[!#]","$"),{b:n+s,rB:!0,c:[{cN:"attr",b:n,endsParent:!0,r:0}],starts:c},{b:a+s,rB:!0,r:0,c:[{cN:"meta",b:a,endsParent:!0,r:0}],starts:c},{cN:"attr",r:0,b:a+t+"$"}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance",i="get set args call";return{k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i,r:0},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}); \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/a11y-dark.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/a11y-dark.min.css new file mode 100644 index 00000000..b93b742a --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/a11y-dark.min.css @@ -0,0 +1,99 @@ +/* a11y-dark theme */ +/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */ +/* @author: ericwbailey */ + +/* Comment */ +.hljs-comment, +.hljs-quote { + color: #d4d0ab; +} + +/* Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #ffa07a; +} + +/* Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f5ab35; +} + +/* Yellow */ +.hljs-attribute { + color: #ffd700; +} + +/* Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #abe338; +} + +/* Blue */ +.hljs-title, +.hljs-section { + color: #00e0e0; +} + +/* Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #dcc6e0; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2b2b2b; + color: #f8f8f2; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +@media screen and (-ms-high-contrast: active) { + .hljs-addition, + .hljs-attribute, + .hljs-built_in, + .hljs-builtin-name, + .hljs-bullet, + .hljs-comment, + .hljs-link, + .hljs-literal, + .hljs-meta, + .hljs-number, + .hljs-params, + .hljs-string, + .hljs-symbol, + .hljs-type, + .hljs-quote { + color: highlight; + } + + .hljs-keyword, + .hljs-selector-tag { + font-weight: bold; + } +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/an-old-hope.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/an-old-hope.min.css new file mode 100644 index 00000000..a6d56f4b --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/an-old-hope.min.css @@ -0,0 +1,89 @@ +/* + +An Old Hope – Star Wars Syntax (c) Gustavo Costa +Original theme - Ocean Dark Theme – by https://github.com/gavsiu +Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom + +*/ + +/* Death Star Comment */ +.hljs-comment, +.hljs-quote +{ + color: #B6B18B; +} + +/* Darth Vader */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion +{ + color: #EB3C54; +} + +/* Threepio */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link +{ + color: #E7CE56; +} + +/* Luke Skywalker */ +.hljs-attribute +{ + color: #EE7C2B; +} + +/* Obi Wan Kenobi */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition +{ + color: #4FB4D7; +} + +/* Yoda */ +.hljs-title, +.hljs-section +{ + color: #78BB65; +} + +/* Mace Windu */ +.hljs-keyword, +.hljs-selector-tag +{ + color: #B45EA4; +} + +/* Millenium Falcon */ +.hljs +{ + display: block; + overflow-x: auto; + background: #1C1D21; + color: #c0c5ce; + padding: 0.5em; +} + +.hljs-emphasis +{ + font-style: italic; +} + +.hljs-strong +{ + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-dark-reasonable.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-dark-reasonable.min.css new file mode 100644 index 00000000..fd41c996 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-dark-reasonable.min.css @@ -0,0 +1,77 @@ +/* + +Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage + +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + line-height: 1.3em; + color: #abb2bf; + background: #282c34; + border-radius: 5px; +} +.hljs-keyword, .hljs-operator { + color: #F92672; +} +.hljs-pattern-match { + color: #F92672; +} +.hljs-pattern-match .hljs-constructor { + color: #61aeee; +} +.hljs-function { + color: #61aeee; +} +.hljs-function .hljs-params { + color: #A6E22E; +} +.hljs-function .hljs-params .hljs-typing { + color: #FD971F; +} +.hljs-module-access .hljs-module { + color: #7e57c2; +} +.hljs-constructor { + color: #e2b93d; +} +.hljs-constructor .hljs-string { + color: #9CCC65; +} +.hljs-comment, .hljs-quote { + color: #b18eb1; + font-style: italic; +} +.hljs-doctag, .hljs-formula { + color: #c678dd; +} +.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst { + color: #e06c75; +} +.hljs-literal { + color: #56b6c2; +} +.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string { + color: #98c379; +} +.hljs-built_in, .hljs-class .hljs-title { + color: #e6c07b; +} +.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number { + color: #d19a66; +} +.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title { + color: #61aeee; +} +.hljs-emphasis { + font-style: italic; +} +.hljs-strong { + font-weight: bold; +} +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-dark.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-dark.min.css new file mode 100644 index 00000000..1616aafe --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-dark.min.css @@ -0,0 +1,96 @@ +/* + +Atom One Dark by Daniel Gamage +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +base: #282c34 +mono-1: #abb2bf +mono-2: #818896 +mono-3: #5c6370 +hue-1: #56b6c2 +hue-2: #61aeee +hue-3: #c678dd +hue-4: #98c379 +hue-5: #e06c75 +hue-5-2: #be5046 +hue-6: #d19a66 +hue-6-2: #e6c07b + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #abb2bf; + background: #282c34; +} + +.hljs-comment, +.hljs-quote { + color: #5c6370; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #c678dd; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e06c75; +} + +.hljs-literal { + color: #56b6c2; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #98c379; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #e6c07b; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #d19a66; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #61aeee; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-light.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-light.min.css new file mode 100644 index 00000000..d5bd1d2a --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/atom-one-light.min.css @@ -0,0 +1,96 @@ +/* + +Atom One Light by Daniel Gamage +Original One Light Syntax theme from https://github.com/atom/one-light-syntax + +base: #fafafa +mono-1: #383a42 +mono-2: #686b77 +mono-3: #a0a1a7 +hue-1: #0184bb +hue-2: #4078f2 +hue-3: #a626a4 +hue-4: #50a14f +hue-5: #e45649 +hue-5-2: #c91243 +hue-6: #986801 +hue-6-2: #c18401 + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #383a42; + background: #fafafa; +} + +.hljs-comment, +.hljs-quote { + color: #a0a1a7; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #a626a4; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e45649; +} + +.hljs-literal { + color: #0184bb; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #50a14f; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #c18401; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #986801; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #4078f2; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/dracula.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/dracula.min.css new file mode 100644 index 00000000..d591db68 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/dracula.min.css @@ -0,0 +1,76 @@ +/* + +Dracula Theme v1.2.0 + +https://github.com/zenorocha/dracula-theme + +Copyright 2015, All rights reserved + +Code licensed under the MIT license +http://zenorocha.mit-license.org + +@author Éverton Ribeiro +@author Zeno Rocha + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #282a36; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-section, +.hljs-link { + color: #8be9fd; +} + +.hljs-function .hljs-keyword { + color: #ff79c6; +} + +.hljs, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-string, +.hljs-title, +.hljs-name, +.hljs-type, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #f1fa8c; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #6272a4; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-title, +.hljs-section, +.hljs-doctag, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/github.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/github.min.css new file mode 100644 index 00000000..791932b8 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/github.min.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/monokai-sublime.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/monokai-sublime.min.css new file mode 100644 index 00000000..2864170d --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/monokai-sublime.min.css @@ -0,0 +1,83 @@ +/* + +Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #23241f; +} + +.hljs, +.hljs-tag, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-strong, +.hljs-emphasis { + color: #a8a8a2; +} + +.hljs-bullet, +.hljs-quote, +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-link { + color: #ae81ff; +} + +.hljs-code, +.hljs-title, +.hljs-section, +.hljs-selector-class { + color: #a6e22e; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-name, +.hljs-attr { + color: #f92672; +} + +.hljs-symbol, +.hljs-attribute { + color: #66d9ef; +} + +.hljs-params, +.hljs-class .hljs-title { + color: #f8f8f2; +} + +.hljs-string, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-variable { + color: #e6db74; +} + +.hljs-comment, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/monokai.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/monokai.min.css new file mode 100644 index 00000000..775d53f9 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/monokai.min.css @@ -0,0 +1,70 @@ +/* +Monokai style - ported by Luigi Maselli - http://grigio.org +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #272822; color: #ddd; +} + +.hljs-tag, +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-strong, +.hljs-name { + color: #f92672; +} + +.hljs-code { + color: #66d9ef; +} + +.hljs-class .hljs-title { + color: white; +} + +.hljs-attribute, +.hljs-symbol, +.hljs-regexp, +.hljs-link { + color: #bf79db; +} + +.hljs-string, +.hljs-bullet, +.hljs-subst, +.hljs-title, +.hljs-section, +.hljs-emphasis, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #a6e22e; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-selector-id { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/solarized-light.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/solarized-light.min.css new file mode 100644 index 00000000..fdcfcc72 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/solarized-light.min.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} + +.hljs-comment, +.hljs-quote { + color: #93a1a1; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/zenburn.min.css b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/zenburn.min.css new file mode 100644 index 00000000..07be5020 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/highlight/styles/zenburn.min.css @@ -0,0 +1,80 @@ +/* + +Zenburn style from voldmar.ru (c) Vladimir Epifanov +based on dark.css by Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #3f3f3f; + color: #dcdcdc; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag { + color: #e3ceab; +} + +.hljs-template-tag { + color: #dcdcdc; +} + +.hljs-number { + color: #8cd0d3; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute { + color: #efdcbc; +} + +.hljs-literal { + color: #efefaf; +} + +.hljs-subst { + color: #8f8f8f; +} + +.hljs-title, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: #efef8f; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #dca3a3; +} + +.hljs-deletion, +.hljs-string, +.hljs-built_in, +.hljs-builtin-name { + color: #cc9393; +} + +.hljs-addition, +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #7f9f7f; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/toc.js b/spring-cloud-info/src/main/resources/static/docs/js/toc.js new file mode 100644 index 00000000..a6e933bf --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/toc.js @@ -0,0 +1,107 @@ +var toctitle = document.getElementById('toctitle'); +var path = window.location.pathname; +if (toctitle != null) { + var oldtoc = toctitle.nextElementSibling; + var newtoc = document.createElement('div'); + newtoc.setAttribute('id', 'tocbot'); + newtoc.setAttribute('class', 'js-toc desktop-toc'); + oldtoc.setAttribute('class', 'mobile-toc'); + oldtoc.parentNode.appendChild(newtoc); + tocbot.init({ + contentSelector: '#content', + headingSelector: 'h1, h2, h3, h4, h5', + positionFixedSelector: 'body', + fixedSidebarOffset: 90, + smoothScroll: false + }); + if (!path.endsWith("index.html") && !path.endsWith("/")) { + var link = document.createElement("a"); + link.setAttribute("href", "index.html"); + link.innerHTML = " Back to index"; + var block = document.createElement("div"); + block.setAttribute('class', 'back-action'); + block.appendChild(link); + var toc = document.getElementById('toc'); + var next = document.getElementById('toctitle').nextElementSibling; + toc.insertBefore(block, next); + } +} + +var headerHtml = '
\n' + + '

\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '

\n' + + '
'; + +var header = document.createElement("div"); +header.innerHTML = headerHtml; +document.body.insertBefore(header, document.body.firstChild); \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/js/tocbot/tocbot.css b/spring-cloud-info/src/main/resources/static/docs/js/tocbot/tocbot.css new file mode 100644 index 00000000..0632de23 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/tocbot/tocbot.css @@ -0,0 +1 @@ +.toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.toc-link::before{background-color:#EEE;content:' ';display:inline-block;height:inherit;left:0;margin-top:-1px;position:absolute;width:2px}.is-active-link::before{background-color:#54BC4B} diff --git a/spring-cloud-info/src/main/resources/static/docs/js/tocbot/tocbot.min.js b/spring-cloud-info/src/main/resources/static/docs/js/tocbot/tocbot.min.js new file mode 100644 index 00000000..943d8fdb --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/js/tocbot/tocbot.min.js @@ -0,0 +1 @@ +!function(e){function t(o){if(n[o])return n[o].exports;var l=n[o]={i:o,l:!1,exports:{}};return e[o].call(l.exports,l,l.exports,t),l.l=!0,l.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){(function(o){var l,i,s;!function(n,o){i=[],l=o(n),void 0!==(s="function"==typeof l?l.apply(t,i):l)&&(e.exports=s)}(void 0!==o?o:this.window||this.global,function(e){"use strict";function t(){for(var e={},t=0;te.fixedSidebarOffset?-1===n.className.indexOf(e.positionFixedClass)&&(n.className+=h+e.positionFixedClass):n.className=n.className.split(h+e.positionFixedClass).join("")}function s(t){var n=document.documentElement.scrollTop||f.scrollTop;e.positionFixedSelector&&i();var o,l=t;if(m&&null!==document.querySelector(e.tocSelector)&&l.length>0){d.call(l,function(t,i){if(t.offsetTop>n+e.headingsOffset+10){return o=l[0===i?i:i-1],!0}if(i===l.length-1)return o=l[l.length-1],!0});var s=document.querySelector(e.tocSelector).querySelectorAll("."+e.linkClass);u.call(s,function(t){t.className=t.className.split(h+e.activeLinkClass).join("")});var c=document.querySelector(e.tocSelector).querySelectorAll("."+e.listItemClass);u.call(c,function(t){t.className=t.className.split(h+e.activeListItemClass).join("")});var a=document.querySelector(e.tocSelector).querySelector("."+e.linkClass+".node-name--"+o.nodeName+'[href="#'+o.id+'"]');-1===a.className.indexOf(e.activeLinkClass)&&(a.className+=h+e.activeLinkClass);var p=a.parentNode;p&&-1===p.className.indexOf(e.activeListItemClass)&&(p.className+=h+e.activeListItemClass);var C=document.querySelector(e.tocSelector).querySelectorAll("."+e.listClass+"."+e.collapsibleClass);u.call(C,function(t){-1===t.className.indexOf(e.isCollapsedClass)&&(t.className+=h+e.isCollapsedClass)}),a.nextSibling&&-1!==a.nextSibling.className.indexOf(e.isCollapsedClass)&&(a.nextSibling.className=a.nextSibling.className.split(h+e.isCollapsedClass).join("")),r(a.parentNode.parentNode)}}function r(t){return-1!==t.className.indexOf(e.collapsibleClass)&&-1!==t.className.indexOf(e.isCollapsedClass)?(t.className=t.className.split(h+e.isCollapsedClass).join(""),r(t.parentNode.parentNode)):t}function c(t){var n=t.target||t.srcElement;"string"==typeof n.className&&-1!==n.className.indexOf(e.linkClass)&&(m=!1)}function a(){m=!0}var u=[].forEach,d=[].some,f=document.body,m=!0,h=" ";return{enableTocAnimation:a,disableTocAnimation:c,render:n,updateToc:s}}},function(e,t){e.exports=function(e){function t(e){return e[e.length-1]}function n(e){return+e.nodeName.split("H").join("")}function o(t){var o={id:t.id,children:[],nodeName:t.nodeName,headingLevel:n(t),textContent:t.textContent.trim()};return e.includeHtml&&(o.childNodes=t.childNodes),o}function l(l,i){for(var s=o(l),r=n(l),c=i,a=t(c),u=a?a.headingLevel:0,d=r-u;d>0;)a=t(c),a&&void 0!==a.children&&(c=a.children),d--;return r>=e.collapseDepth&&(s.isCollapsed=!0),c.push(s),c}function i(t,n){var o=n;e.ignoreSelector&&(o=n.split(",").map(function(t){return t.trim()+":not("+e.ignoreSelector+")"}));try{return document.querySelector(t).querySelectorAll(o)}catch(e){return console.warn("Element not found: "+t),null}}function s(e){return r.call(e,function(e,t){return l(o(t),e.nest),e},{nest:[]})}var r=[].reduce;return{nestHeadingsArray:s,selectHeadings:i}}},function(e,t){function n(e){function t(e){return"a"===e.tagName.toLowerCase()&&(e.hash.length>0||"#"===e.href.charAt(e.href.length-1))&&(n(e.href)===s||n(e.href)+"#"===s)}function n(e){return e.slice(0,e.lastIndexOf("#"))}function l(e){var t=document.getElementById(e.substring(1));t&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())}!function(){document.documentElement.style}();var i=e.duration,s=location.hash?n(location.href):location.href;!function(){function n(n){!t(n.target)||n.target.className.indexOf("no-smooth-scroll")>-1||"#"===n.target.href.charAt(n.target.href.length-2)&&"!"===n.target.href.charAt(n.target.href.length-1)||-1===n.target.className.indexOf(e.linkClass)||o(n.target.hash,{duration:i,callback:function(){l(n.target.hash)}})}document.body.addEventListener("click",n,!1)}()}function o(e,t){function n(e){s=e-i,window.scrollTo(0,c.easing(s,r,u,d)),sp,#preamble>.sectionbody>.paragraph:first-of-type p{line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#0b0a0a;font-weight:bold;margin-top:0;margin-bottom:0.8em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#097dff;line-height:inherit;text-decoration:none}a:hover,a:focus{color:#016be2;text-decoration:underline}a img{border:none}p{font-family:inherit;font-weight:normal;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:0.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:Montserrat, sans-serif;font-weight:400;font-style:normal;color:#000;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:0.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#867c74;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4{font-size:1.125em}h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:Monaco, Menlo, Consolas, "Courier New", monospace;font-weight:normal;color:#3d3d3c;word-break:break-word}ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul.no-bullet,ol.no-bullet{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ul.no-bullet{list-style:none}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:0.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:#000;border-bottom:1px dotted #dddddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:0.5625em 1.25em 0 1.1875em;border-left:1px solid #dddddd}blockquote cite{display:block;font-size:0.9375em;color:rgba(0,0,0,0.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,0.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,0.85)}.vcard{display:inline-block;margin:0 0 1.25em 0;border:1px solid #dddddd;padding:0.625em 0.75em}.vcard li{margin:0;display:block}.vcard .fn{font-weight:bold;font-size:0.9375em}.vevent .summary{font-weight:bold}.vevent abbr{cursor:auto;text-decoration:none;font-weight:bold;border:none;padding:0 0.0625em}#tocbot{padding:0 0 1rem 0;line-height:1.5rem;padding-left:25px}.mobile-toc{padding:0 0 1rem 0;line-height:1.5rem}.mobile-toc li a{display:block;padding:.3rem 0}#tocbot ol li{list-style:none;padding:0;margin:0}#tocbot ol{margin:0;padding:0;padding-left:0.6rem}#tocbot .toc-link{display:block;padding-top:4px;padding-bottom:4px;outline:none}table{background:white;margin-bottom:1.25em;border:solid 1px #cacaca;border-spacing:0}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:0.5em 0.625em 0.625em;font-size:inherit;color:#000;text-align:left}table tr th,table tr td{padding:0.5625em 0.625em;font-size:inherit;color:#000}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;tab-size:4}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-0.05em}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:0.8525em;font-style:normal !important;letter-spacing:0;padding:0.1em 0.3em 0.2em;background-color:rgba(0,0,0,0.05);border-radius:4px;text-rendering:optimizeSpeed}pre,pre>code{line-height:1.85;color:rgba(0,0,0,0.9);font-family:Monaco, Menlo, Consolas, "Courier New", monospace;font-weight:normal;text-rendering:optimizeSpeed;word-break:normal}pre{overflow:auto}em em{font-style:normal}strong strong{font-weight:normal}.keyseq{color:#6b625c}kbd{font-family:Monaco, Menlo, Consolas, "Courier New", monospace;display:inline-block;color:#000;font-size:0.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 0.1em white inset;box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 0.1em white inset;margin:0 0.15em;padding:0.2em 0.5em;vertical-align:middle;position:relative;top:-0.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menu{color:#191715}b.button:before,b.button:after{position:relative;top:-1px;font-weight:normal}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,0.9)}#toc{border-bottom:1px solid #ddddd8;padding-bottom:0.5em}#toc>ul{margin-left:0.125em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:0.5em 0}#toc ul{list-style-type:none}#toc li{line-height:1.3334}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#0b0a0a;font-size:1.2em;display:none}body.toc2{padding-top:90px;text-rendering:optimizeLegibility}#content #toc{border-style:solid;border-width:1px;border-color:#d7d7d7;margin-bottom:1.25em;padding:1.25em;background:#f1f1f1;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{padding-bottom:2rem}#footer #footer-text{padding:2rem 0;border-top:1px solid #efefed}#footer-text{color:rgba(0,0,0,0.6);line-height:1.44}.sect1{padding-bottom:0.625em}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;margin-top:0.1rem;display:block;visibility:hidden;text-align:center;font-weight:normal;color:rgba(0,0,0,0.2)}#content h1>a.anchor:hover,h2>a.anchor:hover,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4>a.anchor:hover,h5>a.anchor:hover,h6>a.anchor:hover{color:#097dff;text-decoration:none}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\0023";font-size:0.85em;display:block;padding-top:0.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#000;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#262321}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:Karla, sans-serif;font-size:1rem}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0;padding:0.6rem 0}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}.admonitionblock>table td.icon{text-align:center;vertical-align:top;padding-top:0.8em;width:80px}.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:Montserrat, sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:0em;padding-right:1.25em;border-left:1px solid #ddddd8}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:0;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#f1f1f1;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:0;border-color:#d7d7d7;margin-bottom:1.25em;padding:1.25em;background:#f1f1f1;border-radius:4px;overflow:scroll}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#0b0a0a;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#282c33;color:#e6e1dc;border-radius:4px}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#282c33;color:#e6e1dc}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class],.listingblock pre:not(.highlight){padding:1em 1.5rem;font-size:0.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto}.literalblock.output pre{color:whitesmoke;background-color:rgba(0,0,0,0.9)}.listingblock{white-space:nowrap}.listingblock pre.highlightjs{padding:0.2rem 0}.listingblock pre.highlightjs>code{padding:1em 1.5rem;border-radius:4px}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:0.8em;font-weight:bold;top:0.425rem;right:0.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:0.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:block;margin-right:.25em}table.pyhltable .linenodiv{background:none !important;padding-right:0 !important}.quoteblock{margin:0 1em 1.25em 1.5em;display:block;text-align:left;padding-left:20px}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,0.85);line-height:1.75;letter-spacing:0}.quoteblock blockquote{margin:0;padding:0;border:0;position:relative}.quoteblock blockquote:before{content:"\201c";font-size:2.75em;font-weight:bold;line-height:0.6em;margin-left:0em;margin-right:1rem;margin-top:0.8rem;color:rgba(0,0,0,0.1);position:absolute;top:0;left:-30px}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-right:0.5ex}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:0.5em 0;border-left:3px solid rgba(0,0,0,0.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 0.75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 0;background-color:#f1f1f1;padding:1rem 1.4rem;border-radius:4px}.verseblock pre{font-family:Monaco, Menlo, Consolas, "Courier New", monospace;font-size:0.9rem;color:rgba(0,0,0,0.85);font-weight:300;text-rendering:optimizeLegibility}.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:0.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:0.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-0.025em;color:rgba(0,0,0,0.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate;overflow-x:scroll}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #cacaca;background:white}table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:#34302d;font-weight:bold}p.tableblock>code:only-child{background:none;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:0.625em}ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}ul.unstyled,ol.unnumbered,ul.checklist{margin-left:0.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:0.85em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}ul.inline{margin:0 auto 0.625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:normal;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:none}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 0.625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-0.5em}.colist>table tr>td:first-of-type{padding:0 0.75em;line-height:1}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:0.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px white;-webkit-box-shadow:0 0 0 1px #dddddd;box-shadow:0 0 0 1px #dddddd}.imageblock.left,.imageblock[style*="float: left"]{margin:0.25em 0.625em 1.25em 0}.imageblock.right,.imageblock[style*="float: right"]{margin:0.25em 0 1.25em 0.625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 0.125em}.image.left,.image.right{margin-top:0.25em;margin-bottom:0.25em;display:inline-block;line-height:0}.image.left{margin-right:0.625em}.image.right{margin-left:0.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:0.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none}sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:0.75em;padding-bottom:0.75em;margin-bottom:0.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-0.25em 0 0.75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 0.375em 0 0.225em;line-height:1.3334;font-size:0.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:0.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-0.625em;margin-bottom:0;padding:0.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:black}.black-background{background-color:black}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000}.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#3f6a22}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";color:#0077b9}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#d88400}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#000 !important;background-color:#ffe157;-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:0.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans", "DejaVu Sans", sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff !important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:0;color:#000 !important;background-color:#ffe157;font-size:12px}b.conum *{color:inherit !important}.conum:not([data-value]):empty{display:none}.admonitionblock{background-color:#ecf1e8;padding:0.8em 0;margin:30px 0;width:auto;border-radius:4px;overflow-x:scroll}.admonitionblock.important{border-left:0px solid #e20000;background-color:#f9ebeb}.admonitionblock.warning{border-left:0px solid #d88400;background-color:#fff9e4}.admonitionblock.tip{border-left:0px solid #0077b9;background-color:#e9f1f6}.admonitionblock.caution{border-left:0px solid #e20000;background-color:#f9ebeb}.admonitionblock .exampleblock>.content{border:0 none;background-color:#fff}#toc a:hover{text-decoration:underline}.admonitionblock>table{margin-bottom:0}.admonitionblock>table td.content{border-left:none}@media print{#tocbot a.toc-link.node-name--H4{display:none}}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 200ms ease-in-out}.is-collapsed{max-height:0}div.back-action,#toc.toc2 div.back-action{padding:0.8rem 0 0 0}div.back-action a,#toc.toc2 div.back-action a{position:relative;display:inline-block;padding:0.6rem 1.2rem;padding-left:35px}div.back-action a span,#toc.toc2 div.back-action a span{position:absolute;left:5px;top:5px;display:block;color:#333;height:26px;width:26px;border-radius:13px}div.back-action a i,#toc.toc2 div.back-action a i{position:absolute;top:5px;left:5px}div.back-action a:hover span,#toc.toc2 div.back-action a:hover span{color:#000}#tocbot.desktop-toc{padding-top:0.8rem}#header-spring{position:absolute;text-rendering:optimizeLegibility;top:0;left:0;right:0;height:90px;margin:0 1rem;padding:0 1rem;border-bottom:1px solid #ddddd8;border-top:3px solid #6BB344}#header-spring h1{margin:0;padding:0;font-size:22px;text-align:left;line-height:86px;padding-left:0.6rem}#header-spring h1 svg{width:200px}#header-spring h1 svg .st0{fill:#6BB344}#header-spring h1 svg .st2{fill:#444}body.book #header-spring{position:relative;top:auto;left:auto;right:auto;margin:0}body.book #header>h1:only-child{border:0 none;padding-bottom:1.2rem;font-size:1.8rem}body.book #header,body.book #content,body.book #footnotes,body.book #footer{margin:0 auto}body.toc2 #header-spring{position:absolute;left:0;right:0;top:0}body.toc2 #header>h1:only-child{font-size:2.2rem}body.toc2 #header,body.toc2 #content,body.toc2 #footnotes,body.toc2 #footer{margin:0 auto}body.toc2 #content{padding-top:2rem}#header,#content,#footnotes,#footer{width:100%;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:0.9375em;padding-right:0.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{margin-top:2.55rem;margin-bottom:0.5em;margin-bottom:0.5em}#header>h1:first-child+#toc{margin-top:8px;border-top:0 none}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:0;padding-bottom:2.25em;padding-left:0.25em;color:rgba(0,0,0,0.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-0.125em}#header .details span.email a{color:rgba(0,0,0,0.85)}#header .details br{display:none}#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,0.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,0.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1.5rem;margin-bottom:1.25rem}h1{font-size:2.2rem;letter-spacing:-1px}h1,h2,h3,h4,h5,h6{font-weight:normal;font-family:Montserrat, Arial, Helvetica, sans-serif}h1:focus,h2:focus,h3:focus,h4:focus,h5:focus,h6:focus{box-shadow:none;outline:none}h2,h3,h4,h5,h6{padding:.8rem 0 .4rem}h1{font-size:1.75em}h2{font-size:1.6rem;letter-spacing:-1px}h3{font-size:1.5rem}h4{font-size:1.4rem}h5{font-size:1.3rem}h6{font-size:1.2rem}pre.highlight{background:#232323;color:#e6e1dc;border-radius:4px}pre.highlight code{color:#e6e1dc}pre.highlight a,#toc.toc2 a{color:#000;font-size:1rem}pre.highlight ul.sectlevel1,#toc.toc2 ul.sectlevel1{padding-left:0.2rem}pre.highlight ul.sectlevel1 li,#toc.toc2 ul.sectlevel1 li{line-height:1.4rem}::selection{background-color:#d1ff79}.literalblock pre::selection,.listingblock pre[class="highlight"]::selection,.highlight::selection,pre::selection,.highlight code::selection,.highlight code span::selection{background:rgba(255,255,255,0.2) !important}body.book #header{margin-bottom:2rem}body.toc2 #header{margin-bottom:0}.desktop-toc{display:none}.admonitionblock td.icon{display:none}.admonitionblock>table td.content{padding-left:1.25em}@media only screen and (min-width: 768px){#toctitle{font-size:1.375em}.sect1{padding-bottom:1.25em}.mobile-toc{display:none}.desktop-toc{display:block}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:0.90625em}.admonitionblock td.icon{display:table-cell}.admonitionblock>table td.content{padding-left:0}body.toc2{padding-right:0}body.toc2 #toc.toc2{position:absolute;margin-top:0 !important;width:15em;top:0;border-top-width:0 !important;border-bottom-width:0 !important;margin-left:-15.9375em;z-index:1000;padding:0 1em 1.25em 0em;overflow:auto}body.toc2 #toc.toc2 #toctitle{margin-top:0;margin-bottom:0.8rem;font-size:1.2em}body.toc2 #toc.toc2>ul{font-size:0.9em;margin-bottom:0}body.toc2 #toc.toc2 ul ul{margin-left:0;padding-left:1em}body.toc2 #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:0.5em;margin-bottom:0.5em}body.toc2 #header,body.toc2 #content,body.toc2 #footnotes,body.toc2 #footer{padding-left:15.9375em;max-width:none}body.book #header-spring h1{max-width:1400px;margin:0 auto}body.book #header,body.book #content,body.book #footnotes,body.book #footer{max-width:1400px}body.is-position-fixed #toc.toc2{position:fixed;height:100%}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:1.75em}h2{font-size:1.6em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.5em}h4{font-size:1.4em}h5{font-size:1.2em}h6{font-size:1.2em}#tocbot a.toc-link.node-name--H1{font-style:italic}#tocbot ol{margin:0;padding:0;padding-left:0.6rem}#tocbot ol li{list-style:none;padding:0 0;margin:0;display:block}#tocbot{z-index:999}#tocbot .toc-link{position:relative;display:block;z-index:999;padding-right:5px;padding-top:4px;padding-bottom:4px}#tocbot .is-active-link{padding-right:3px;border-right:3px solid #6BB344}}@media only screen and (min-width: 768px){#tocbot>ul.toc-list{margin-bottom:0.5em;margin-left:0.125em}#tocbot ul.sectlevel0,#tocbot a.toc-link.node-name--H1+ul{padding-left:0}#tocbot a.toc-link{height:100%}.is-collapsible{max-height:3000px;overflow:hidden}.is-collapsed{max-height:0}.is-active-link{font-weight:700}}@media only screen and (min-width: 768px){body.toc2 #header,body.toc2 #content,body.toc2 #footer{background-repeat:repeat-y;background-position:14em 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDE0NUNENzNGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDE0NUNENzRGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEMTQ1Q0Q3MUYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEMTQ1Q0Q3MkYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjmGxxYAAAAGUExURd3d2AAAAJlCnKAAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=)}}@media only screen and (min-width: 1280px){body.toc2{padding-right:0}body.toc2 #toc.toc2{width:25em;left:auto;margin-left:-26.9375em}body.toc2 #toc.toc2 #toctitle{font-size:1.375em}body.toc2 #toc.toc2>ul{font-size:0.95em}body.toc2 #toc.toc2 ul ul{padding-left:1.25em}body.toc2 body.toc2.toc-right{padding-left:0;padding-right:20em}body.toc2 #header,body.toc2 #content,body.toc2 #footnotes,body.toc2 #footer{padding-left:26.9375em;max-width:1400px}body.toc2 #header-spring h1{margin:0 auto;max-width:1400px}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:0.8125em}body.toc2 #header,body.toc2 #content,body.toc2 #footer{background-repeat:repeat-y;background-position:24em 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDE0NUNENzNGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDE0NUNENzRGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEMTQ1Q0Q3MUYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEMTQ1Q0Q3MkYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjmGxxYAAAAGUExURd3d2AAAAJlCnKAAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=)}} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/favicon.ico b/spring-cloud-info/src/main/resources/static/docs/reference/html/favicon.ico new file mode 100644 index 00000000..1a4956e6 Binary files /dev/null and b/spring-cloud-info/src/main/resources/static/docs/reference/html/favicon.ico differ diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/highlight.min.js b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/highlight.min.js new file mode 100644 index 00000000..dcbbb4c7 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/highlight.min.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.13.1 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=M.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function c(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function u(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"===e.event?o:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function l(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):B(a.k).forEach(function(e){c(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.endSameAsBegin&&(a.e=a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return s("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var u=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=u.length?t(u.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e){return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}function c(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=o(n.c[t].bR.exec(e)[0])),n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function s(e,n){return!a&&r(n.iR,e)}function p(e,n){var t=R.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function d(e,n,t,r){var a=r?"":j.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=p(E,r),e?(M+=e[1],a+=d(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function b(){var e="string"==typeof E.sL;if(e&&!L[E.sL])return n(k);var t=e?f(E.sL,k,!0,B[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(B[E.sL]=t.top),d(t.language,t.value,!1,!0)}function v(){y+=null!=E.sL?b():h(),k=""}function m(e){y+=e.cN?d(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function N(e,n){if(k+=e,null==n)return v(),0;var t=c(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),v(),t.rB||t.eB||(k=n)),m(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),v(),a.eE&&(k=n));do E.cN&&(y+=I),E.skip||E.sL||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),m(r.starts,"")),a.rE?0:n.length}if(s(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var R=w(e);if(!R)throw new Error('Unknown language: "'+e+'"');l(R);var x,E=i||R,B={},y="";for(x=E;x!==R;x=x.parent)x.cN&&(y=d(x.cN,"",!0)+y);var k="",M=0;try{for(var C,A,S=0;;){if(E.t.lastIndex=S,C=E.t.exec(t),!C)break;A=N(t.substring(S,C.index),C[0]),S=C.index+A}for(N(t.substr(S)),x=E;x.parent;x=x.parent)x.cN&&(y+=I);return{r:M,value:y,language:e,top:E}}catch(O){if(O.message&&-1!==O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function g(e,t){t=t||j.languages||B(L);var r={r:0,value:n(e)},a=r;return t.filter(w).filter(x).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return j.tabReplace||j.useBR?e.replace(C,function(e,n){return j.useBR&&"\n"===e?"
":j.tabReplace?n.replace(/\t/g,j.tabReplace):""}):e}function d(e,n,t){var r=n?y[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n,t,r,o,s,l=i(e);a(l)||(j.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=l?f(l,s,!0):g(s),t=c(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=u(t,c(o),s)),r.value=p(r.value),e.innerHTML=r.value,e.className=d(e.className,l,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){j=o(j,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,h)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=L[n]=t(e);r.aliases&&r.aliases.forEach(function(e){y[e]=n})}function R(){return B(L)}function w(e){return e=(e||"").toLowerCase(),L[e]||L[y[e]]}function x(e){var n=w(e);return n&&!n.disableAutodetect}var E=[],B=Object.keys,L={},y={},k=/^(no-?highlight|plain|text)$/i,M=/\blang(?:uage)?-([\w-]+)\b/i,C=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,I="
",j={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=h,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.autoDetection=x,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\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/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|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)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{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",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]\n/,sL:"bash"}}],i:")?[^\s\(]+(\s+[^\s\(]+)\s*=/,r:5,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"type",b://,k:"reified",r:0},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:t,r:0,c:[{b:/:/,e:/[=,\/]/,eW:!0,c:[{cN:"type",b:e.UIR},e.CLCM,e.CBCM],r:0},e.CLCM,e.CBCM,s,l,c,e.CNM]},e.CBCM]},{cN:"class",bK:"class interface trait",e:/[:\{(]|$/,eE:!0,i:"extends implements",c:[{bK:"public protected internal private constructor"},e.UTM,{cN:"type",b://,eB:!0,eE:!0,r:0},{cN:"type",b:/[,:]\s*/,e:/[<\(,]|$/,eB:!0,rE:!0},s,l]},c,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},o]}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="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",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("properties",function(r){var t="[ \\t\\f]*",e="[ \\t\\f]+",s="("+t+"[:=]"+t+"|"+e+")",n="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",c={e:s,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[r.C("^\\s*[!#]","$"),{b:n+s,rB:!0,c:[{cN:"attr",b:n,endsParent:!0,r:0}],starts:c},{b:a+s,rB:!0,r:0,c:[{cN:"meta",b:a,endsParent:!0,r:0}],starts:c},{cN:"attr",r:0,b:a+t+"$"}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance",i="get set args call";return{k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i,r:0},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}); \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/a11y-dark.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/a11y-dark.min.css new file mode 100644 index 00000000..b93b742a --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/a11y-dark.min.css @@ -0,0 +1,99 @@ +/* a11y-dark theme */ +/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */ +/* @author: ericwbailey */ + +/* Comment */ +.hljs-comment, +.hljs-quote { + color: #d4d0ab; +} + +/* Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #ffa07a; +} + +/* Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f5ab35; +} + +/* Yellow */ +.hljs-attribute { + color: #ffd700; +} + +/* Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #abe338; +} + +/* Blue */ +.hljs-title, +.hljs-section { + color: #00e0e0; +} + +/* Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #dcc6e0; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2b2b2b; + color: #f8f8f2; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +@media screen and (-ms-high-contrast: active) { + .hljs-addition, + .hljs-attribute, + .hljs-built_in, + .hljs-builtin-name, + .hljs-bullet, + .hljs-comment, + .hljs-link, + .hljs-literal, + .hljs-meta, + .hljs-number, + .hljs-params, + .hljs-string, + .hljs-symbol, + .hljs-type, + .hljs-quote { + color: highlight; + } + + .hljs-keyword, + .hljs-selector-tag { + font-weight: bold; + } +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/an-old-hope.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/an-old-hope.min.css new file mode 100644 index 00000000..a6d56f4b --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/an-old-hope.min.css @@ -0,0 +1,89 @@ +/* + +An Old Hope – Star Wars Syntax (c) Gustavo Costa +Original theme - Ocean Dark Theme – by https://github.com/gavsiu +Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom + +*/ + +/* Death Star Comment */ +.hljs-comment, +.hljs-quote +{ + color: #B6B18B; +} + +/* Darth Vader */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion +{ + color: #EB3C54; +} + +/* Threepio */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link +{ + color: #E7CE56; +} + +/* Luke Skywalker */ +.hljs-attribute +{ + color: #EE7C2B; +} + +/* Obi Wan Kenobi */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition +{ + color: #4FB4D7; +} + +/* Yoda */ +.hljs-title, +.hljs-section +{ + color: #78BB65; +} + +/* Mace Windu */ +.hljs-keyword, +.hljs-selector-tag +{ + color: #B45EA4; +} + +/* Millenium Falcon */ +.hljs +{ + display: block; + overflow-x: auto; + background: #1C1D21; + color: #c0c5ce; + padding: 0.5em; +} + +.hljs-emphasis +{ + font-style: italic; +} + +.hljs-strong +{ + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-dark-reasonable.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-dark-reasonable.min.css new file mode 100644 index 00000000..fd41c996 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-dark-reasonable.min.css @@ -0,0 +1,77 @@ +/* + +Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage + +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + line-height: 1.3em; + color: #abb2bf; + background: #282c34; + border-radius: 5px; +} +.hljs-keyword, .hljs-operator { + color: #F92672; +} +.hljs-pattern-match { + color: #F92672; +} +.hljs-pattern-match .hljs-constructor { + color: #61aeee; +} +.hljs-function { + color: #61aeee; +} +.hljs-function .hljs-params { + color: #A6E22E; +} +.hljs-function .hljs-params .hljs-typing { + color: #FD971F; +} +.hljs-module-access .hljs-module { + color: #7e57c2; +} +.hljs-constructor { + color: #e2b93d; +} +.hljs-constructor .hljs-string { + color: #9CCC65; +} +.hljs-comment, .hljs-quote { + color: #b18eb1; + font-style: italic; +} +.hljs-doctag, .hljs-formula { + color: #c678dd; +} +.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst { + color: #e06c75; +} +.hljs-literal { + color: #56b6c2; +} +.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string { + color: #98c379; +} +.hljs-built_in, .hljs-class .hljs-title { + color: #e6c07b; +} +.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number { + color: #d19a66; +} +.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title { + color: #61aeee; +} +.hljs-emphasis { + font-style: italic; +} +.hljs-strong { + font-weight: bold; +} +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-dark.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-dark.min.css new file mode 100644 index 00000000..1616aafe --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-dark.min.css @@ -0,0 +1,96 @@ +/* + +Atom One Dark by Daniel Gamage +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +base: #282c34 +mono-1: #abb2bf +mono-2: #818896 +mono-3: #5c6370 +hue-1: #56b6c2 +hue-2: #61aeee +hue-3: #c678dd +hue-4: #98c379 +hue-5: #e06c75 +hue-5-2: #be5046 +hue-6: #d19a66 +hue-6-2: #e6c07b + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #abb2bf; + background: #282c34; +} + +.hljs-comment, +.hljs-quote { + color: #5c6370; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #c678dd; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e06c75; +} + +.hljs-literal { + color: #56b6c2; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #98c379; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #e6c07b; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #d19a66; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #61aeee; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-light.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-light.min.css new file mode 100644 index 00000000..d5bd1d2a --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/atom-one-light.min.css @@ -0,0 +1,96 @@ +/* + +Atom One Light by Daniel Gamage +Original One Light Syntax theme from https://github.com/atom/one-light-syntax + +base: #fafafa +mono-1: #383a42 +mono-2: #686b77 +mono-3: #a0a1a7 +hue-1: #0184bb +hue-2: #4078f2 +hue-3: #a626a4 +hue-4: #50a14f +hue-5: #e45649 +hue-5-2: #c91243 +hue-6: #986801 +hue-6-2: #c18401 + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #383a42; + background: #fafafa; +} + +.hljs-comment, +.hljs-quote { + color: #a0a1a7; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #a626a4; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e45649; +} + +.hljs-literal { + color: #0184bb; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #50a14f; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #c18401; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #986801; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #4078f2; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/dracula.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/dracula.min.css new file mode 100644 index 00000000..d591db68 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/dracula.min.css @@ -0,0 +1,76 @@ +/* + +Dracula Theme v1.2.0 + +https://github.com/zenorocha/dracula-theme + +Copyright 2015, All rights reserved + +Code licensed under the MIT license +http://zenorocha.mit-license.org + +@author Éverton Ribeiro +@author Zeno Rocha + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #282a36; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-section, +.hljs-link { + color: #8be9fd; +} + +.hljs-function .hljs-keyword { + color: #ff79c6; +} + +.hljs, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-string, +.hljs-title, +.hljs-name, +.hljs-type, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #f1fa8c; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #6272a4; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-title, +.hljs-section, +.hljs-doctag, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/github.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/github.min.css new file mode 100644 index 00000000..791932b8 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/github.min.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/monokai-sublime.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/monokai-sublime.min.css new file mode 100644 index 00000000..2864170d --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/monokai-sublime.min.css @@ -0,0 +1,83 @@ +/* + +Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #23241f; +} + +.hljs, +.hljs-tag, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-strong, +.hljs-emphasis { + color: #a8a8a2; +} + +.hljs-bullet, +.hljs-quote, +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-link { + color: #ae81ff; +} + +.hljs-code, +.hljs-title, +.hljs-section, +.hljs-selector-class { + color: #a6e22e; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-name, +.hljs-attr { + color: #f92672; +} + +.hljs-symbol, +.hljs-attribute { + color: #66d9ef; +} + +.hljs-params, +.hljs-class .hljs-title { + color: #f8f8f2; +} + +.hljs-string, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-variable { + color: #e6db74; +} + +.hljs-comment, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/monokai.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/monokai.min.css new file mode 100644 index 00000000..775d53f9 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/monokai.min.css @@ -0,0 +1,70 @@ +/* +Monokai style - ported by Luigi Maselli - http://grigio.org +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #272822; color: #ddd; +} + +.hljs-tag, +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-strong, +.hljs-name { + color: #f92672; +} + +.hljs-code { + color: #66d9ef; +} + +.hljs-class .hljs-title { + color: white; +} + +.hljs-attribute, +.hljs-symbol, +.hljs-regexp, +.hljs-link { + color: #bf79db; +} + +.hljs-string, +.hljs-bullet, +.hljs-subst, +.hljs-title, +.hljs-section, +.hljs-emphasis, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #a6e22e; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-selector-id { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/solarized-light.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/solarized-light.min.css new file mode 100644 index 00000000..fdcfcc72 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/solarized-light.min.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} + +.hljs-comment, +.hljs-quote { + color: #93a1a1; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/zenburn.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/zenburn.min.css new file mode 100644 index 00000000..07be5020 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/highlight/styles/zenburn.min.css @@ -0,0 +1,80 @@ +/* + +Zenburn style from voldmar.ru (c) Vladimir Epifanov +based on dark.css by Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #3f3f3f; + color: #dcdcdc; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag { + color: #e3ceab; +} + +.hljs-template-tag { + color: #dcdcdc; +} + +.hljs-number { + color: #8cd0d3; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute { + color: #efdcbc; +} + +.hljs-literal { + color: #efefaf; +} + +.hljs-subst { + color: #8f8f8f; +} + +.hljs-title, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: #efef8f; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #dca3a3; +} + +.hljs-deletion, +.hljs-string, +.hljs-built_in, +.hljs-builtin-name { + color: #cc9393; +} + +.hljs-addition, +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #7f9f7f; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/toc.js b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/toc.js new file mode 100644 index 00000000..a6e933bf --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/toc.js @@ -0,0 +1,107 @@ +var toctitle = document.getElementById('toctitle'); +var path = window.location.pathname; +if (toctitle != null) { + var oldtoc = toctitle.nextElementSibling; + var newtoc = document.createElement('div'); + newtoc.setAttribute('id', 'tocbot'); + newtoc.setAttribute('class', 'js-toc desktop-toc'); + oldtoc.setAttribute('class', 'mobile-toc'); + oldtoc.parentNode.appendChild(newtoc); + tocbot.init({ + contentSelector: '#content', + headingSelector: 'h1, h2, h3, h4, h5', + positionFixedSelector: 'body', + fixedSidebarOffset: 90, + smoothScroll: false + }); + if (!path.endsWith("index.html") && !path.endsWith("/")) { + var link = document.createElement("a"); + link.setAttribute("href", "index.html"); + link.innerHTML = " Back to index"; + var block = document.createElement("div"); + block.setAttribute('class', 'back-action'); + block.appendChild(link); + var toc = document.getElementById('toc'); + var next = document.getElementById('toctitle').nextElementSibling; + toc.insertBefore(block, next); + } +} + +var headerHtml = '
\n' + + '

\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '

\n' + + '
'; + +var header = document.createElement("div"); +header.innerHTML = headerHtml; +document.body.insertBefore(header, document.body.firstChild); \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/tocbot/tocbot.css b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/tocbot/tocbot.css new file mode 100644 index 00000000..0632de23 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/tocbot/tocbot.css @@ -0,0 +1 @@ +.toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.toc-link::before{background-color:#EEE;content:' ';display:inline-block;height:inherit;left:0;margin-top:-1px;position:absolute;width:2px}.is-active-link::before{background-color:#54BC4B} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/html/js/tocbot/tocbot.min.js b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/tocbot/tocbot.min.js new file mode 100644 index 00000000..943d8fdb --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/html/js/tocbot/tocbot.min.js @@ -0,0 +1 @@ +!function(e){function t(o){if(n[o])return n[o].exports;var l=n[o]={i:o,l:!1,exports:{}};return e[o].call(l.exports,l,l.exports,t),l.l=!0,l.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){(function(o){var l,i,s;!function(n,o){i=[],l=o(n),void 0!==(s="function"==typeof l?l.apply(t,i):l)&&(e.exports=s)}(void 0!==o?o:this.window||this.global,function(e){"use strict";function t(){for(var e={},t=0;te.fixedSidebarOffset?-1===n.className.indexOf(e.positionFixedClass)&&(n.className+=h+e.positionFixedClass):n.className=n.className.split(h+e.positionFixedClass).join("")}function s(t){var n=document.documentElement.scrollTop||f.scrollTop;e.positionFixedSelector&&i();var o,l=t;if(m&&null!==document.querySelector(e.tocSelector)&&l.length>0){d.call(l,function(t,i){if(t.offsetTop>n+e.headingsOffset+10){return o=l[0===i?i:i-1],!0}if(i===l.length-1)return o=l[l.length-1],!0});var s=document.querySelector(e.tocSelector).querySelectorAll("."+e.linkClass);u.call(s,function(t){t.className=t.className.split(h+e.activeLinkClass).join("")});var c=document.querySelector(e.tocSelector).querySelectorAll("."+e.listItemClass);u.call(c,function(t){t.className=t.className.split(h+e.activeListItemClass).join("")});var a=document.querySelector(e.tocSelector).querySelector("."+e.linkClass+".node-name--"+o.nodeName+'[href="#'+o.id+'"]');-1===a.className.indexOf(e.activeLinkClass)&&(a.className+=h+e.activeLinkClass);var p=a.parentNode;p&&-1===p.className.indexOf(e.activeListItemClass)&&(p.className+=h+e.activeListItemClass);var C=document.querySelector(e.tocSelector).querySelectorAll("."+e.listClass+"."+e.collapsibleClass);u.call(C,function(t){-1===t.className.indexOf(e.isCollapsedClass)&&(t.className+=h+e.isCollapsedClass)}),a.nextSibling&&-1!==a.nextSibling.className.indexOf(e.isCollapsedClass)&&(a.nextSibling.className=a.nextSibling.className.split(h+e.isCollapsedClass).join("")),r(a.parentNode.parentNode)}}function r(t){return-1!==t.className.indexOf(e.collapsibleClass)&&-1!==t.className.indexOf(e.isCollapsedClass)?(t.className=t.className.split(h+e.isCollapsedClass).join(""),r(t.parentNode.parentNode)):t}function c(t){var n=t.target||t.srcElement;"string"==typeof n.className&&-1!==n.className.indexOf(e.linkClass)&&(m=!1)}function a(){m=!0}var u=[].forEach,d=[].some,f=document.body,m=!0,h=" ";return{enableTocAnimation:a,disableTocAnimation:c,render:n,updateToc:s}}},function(e,t){e.exports=function(e){function t(e){return e[e.length-1]}function n(e){return+e.nodeName.split("H").join("")}function o(t){var o={id:t.id,children:[],nodeName:t.nodeName,headingLevel:n(t),textContent:t.textContent.trim()};return e.includeHtml&&(o.childNodes=t.childNodes),o}function l(l,i){for(var s=o(l),r=n(l),c=i,a=t(c),u=a?a.headingLevel:0,d=r-u;d>0;)a=t(c),a&&void 0!==a.children&&(c=a.children),d--;return r>=e.collapseDepth&&(s.isCollapsed=!0),c.push(s),c}function i(t,n){var o=n;e.ignoreSelector&&(o=n.split(",").map(function(t){return t.trim()+":not("+e.ignoreSelector+")"}));try{return document.querySelector(t).querySelectorAll(o)}catch(e){return console.warn("Element not found: "+t),null}}function s(e){return r.call(e,function(e,t){return l(o(t),e.nest),e},{nest:[]})}var r=[].reduce;return{nestHeadingsArray:s,selectHeadings:i}}},function(e,t){function n(e){function t(e){return"a"===e.tagName.toLowerCase()&&(e.hash.length>0||"#"===e.href.charAt(e.href.length-1))&&(n(e.href)===s||n(e.href)+"#"===s)}function n(e){return e.slice(0,e.lastIndexOf("#"))}function l(e){var t=document.getElementById(e.substring(1));t&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())}!function(){document.documentElement.style}();var i=e.duration,s=location.hash?n(location.href):location.href;!function(){function n(n){!t(n.target)||n.target.className.indexOf("no-smooth-scroll")>-1||"#"===n.target.href.charAt(n.target.href.length-2)&&"!"===n.target.href.charAt(n.target.href.length-1)||-1===n.target.className.indexOf(e.linkClass)||o(n.target.hash,{duration:i,callback:function(){l(n.target.hash)}})}document.body.addEventListener("click",n,!1)}()}function o(e,t){function n(e){s=e-i,window.scrollTo(0,c.easing(s,r,u,d)),s + + + + + + +Rest API + + + + + + + + + + +
+
+

Spring Cloud Versions

+
+
+

Gets all the available Spring Cloud release trains.

+
+
+

cURL Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversions/curl-request.adoc[]

+
+
+
+

HTTPie Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversions/httpie-request.adoc[]

+
+
+
+

HTTP Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversions/http-request.adoc[]

+
+
+
+

Response

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversions/http-response.adoc[]

+
+
+
+

Response Fields

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversions/response-fields.adoc[]

+
+
+
+
+
+

Spring Cloud Version Given Spring Boot Version

+
+
+

Gets the Spring Cloud release train version given a Spring Boot version.

+
+
+

Path Parameters

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversion/path-parameters.adoc[]

+
+
+
+

cURL Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversion/curl-request.adoc[]

+
+
+
+

HTTPie Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversion/httpie-request.adoc[]

+
+
+
+

HTTP Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversion/http-request.adoc[]

+
+
+
+

HTTP Response

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversion/http-response.adoc[]

+
+
+
+

Response Fields

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/springcloudversion/response-fields.adoc[]

+
+
+
+
+
+

Spring Cloud Project Versions

+
+
+

Get the Spring Cloud project versions for a given Spring Cloud release train.

+
+
+

cURL Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/bomversions/curl-request.adoc[]

+
+
+
+

HTTPie Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/bomversions/httpie-request.adoc[]

+
+
+
+

HTTP Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/bomversions/http-request.adoc[]

+
+
+
+

HTTP Response

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/bomversions/http-response.adoc[]

+
+
+
+
+
+

Upcoming Spring Cloud Releases

+
+
+

Gets all the upcoming Spring Cloud releases.

+
+
+

cURL Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestones/curl-request.adoc[]

+
+
+
+

HTTPie Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestones/httpie-request.adoc[]

+
+
+
+

HTTP Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestones/http-request.adoc[]

+
+
+
+

HTTP Response

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestones/http-response.adoc[]

+
+
+
+
+
+

Get Spring Cloud Release Date

+
+
+

Gets the tentative date given an upcoming Spring Cloud release train name.

+
+
+

Path Parameters

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestoneduedate/path-parameters.adoc[]

+
+
+
+

cURL Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestoneduedate/curl-request.adoc[]

+
+
+
+

HTTPie Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestoneduedate/httpie-request.adoc[]

+
+
+
+

HTTP Request

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestoneduedate/http-request.adoc[]

+
+
+
+

HTTP Response

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestoneduedate/http-response.adoc[]

+
+
+
+

Response Fields

+
+

Unresolved directive in spring-cloud-info.adoc - include::../../target/generated-snippets/milestoneduedate/response-fields.adoc[]

+
+
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/css/spring.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/css/spring.css new file mode 100644 index 00000000..40821db3 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/css/spring.css @@ -0,0 +1 @@ +@import url("https://fonts.googleapis.com/css?family=Karla:400,700|Montserrat:400,700");/*! normalize.css v2.1.2 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}script{display:none !important}html,body{font-size:100%}html{font-family:Karla, sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}body{background:white;color:#000;padding:0;margin:0;font-size:16px;font-family:Karla, sans-serif;font-weight:normal;font-style:normal;line-height:1.6em;position:relative;cursor:auto}a:hover{cursor:pointer}img,object,embed{max-width:100%;height:auto}object,embed{height:100%}img{-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important}.left{float:left !important}.right{float:right !important}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}.hide{display:none}.antialiased{-webkit-font-smoothing:antialiased}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}select{width:100%}object,svg{display:inline-block;vertical-align:middle}.center{margin-left:auto;margin-right:auto}.spread{width:100%}p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{line-height:1.6}.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#0b0a0a;font-weight:bold;margin-top:0;margin-bottom:0.8em}div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}a{color:#097dff;line-height:inherit;text-decoration:none}a:hover,a:focus{color:#016be2;text-decoration:underline}a img{border:none}p{font-family:inherit;font-weight:normal;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}p aside{font-size:0.875em;line-height:1.35;font-style:italic}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:Montserrat, sans-serif;font-weight:400;font-style:normal;color:#000;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:0.5em;line-height:1.0125em}h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#867c74;line-height:0}h1{font-size:2.125em}h2{font-size:1.6875em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}h4{font-size:1.125em}h5{font-size:1.125em}h6{font-size:1em}hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:Monaco, Menlo, Consolas, "Courier New", monospace;font-weight:normal;color:#3d3d3c;word-break:break-word}ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}ul,ol{margin-left:1.5em}ul.no-bullet,ol.no-bullet{margin-left:1.5em}ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}ul.square{list-style-type:square}ul.circle{list-style-type:circle}ul.disc{list-style-type:disc}ul.no-bullet{list-style:none}ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}dl dt{margin-bottom:0.3125em;font-weight:bold}dl dd{margin-bottom:1.25em}abbr,acronym{text-transform:uppercase;font-size:90%;color:#000;border-bottom:1px dotted #dddddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25em;padding:0.5625em 1.25em 0 1.1875em;border-left:1px solid #dddddd}blockquote cite{display:block;font-size:0.9375em;color:rgba(0,0,0,0.6)}blockquote cite:before{content:"\2014 \0020"}blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,0.6)}blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,0.85)}.vcard{display:inline-block;margin:0 0 1.25em 0;border:1px solid #dddddd;padding:0.625em 0.75em}.vcard li{margin:0;display:block}.vcard .fn{font-weight:bold;font-size:0.9375em}.vevent .summary{font-weight:bold}.vevent abbr{cursor:auto;text-decoration:none;font-weight:bold;border:none;padding:0 0.0625em}#tocbot{padding:0 0 1rem 0;line-height:1.5rem;padding-left:25px}.mobile-toc{padding:0 0 1rem 0;line-height:1.5rem}.mobile-toc li a{display:block;padding:.3rem 0}#tocbot ol li{list-style:none;padding:0;margin:0}#tocbot ol{margin:0;padding:0;padding-left:0.6rem}#tocbot .toc-link{display:block;padding-top:4px;padding-bottom:4px;outline:none}table{background:white;margin-bottom:1.25em;border:solid 1px #cacaca;border-spacing:0}table thead,table tfoot{background:#f7f8f7;font-weight:bold}table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:0.5em 0.625em 0.625em;font-size:inherit;color:#000;text-align:left}table tr th,table tr td{padding:0.5625em 0.625em;font-size:inherit;color:#000}table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;tab-size:4}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-0.05em}.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}.clearfix:after,.float-group:after{clear:both}*:not(pre)>code{font-size:0.8525em;font-style:normal !important;letter-spacing:0;padding:0.1em 0.3em 0.2em;background-color:rgba(0,0,0,0.05);border-radius:4px;text-rendering:optimizeSpeed}pre,pre>code{line-height:1.85;color:rgba(0,0,0,0.9);font-family:Monaco, Menlo, Consolas, "Courier New", monospace;font-weight:normal;text-rendering:optimizeSpeed;word-break:normal}pre{overflow:auto}em em{font-style:normal}strong strong{font-weight:normal}.keyseq{color:#6b625c}kbd{font-family:Monaco, Menlo, Consolas, "Courier New", monospace;display:inline-block;color:#000;font-size:0.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 0.1em white inset;box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 0.1em white inset;margin:0 0.15em;padding:0.2em 0.5em;vertical-align:middle;position:relative;top:-0.1em;white-space:nowrap}.keyseq kbd:first-child{margin-left:0}.keyseq kbd:last-child{margin-right:0}.menuseq,.menu{color:#191715}b.button:before,b.button:after{position:relative;top:-1px;font-weight:normal}b.button:before{content:"[";padding:0 3px 0 2px}b.button:after{content:"]";padding:0 2px 0 3px}p a>code:hover{color:rgba(0,0,0,0.9)}#toc{border-bottom:1px solid #ddddd8;padding-bottom:0.5em}#toc>ul{margin-left:0.125em}#toc ul.sectlevel0>li>a{font-style:italic}#toc ul.sectlevel0 ul.sectlevel1{margin:0.5em 0}#toc ul{list-style-type:none}#toc li{line-height:1.3334}#toc a{text-decoration:none}#toc a:active{text-decoration:underline}#toctitle{color:#0b0a0a;font-size:1.2em;display:none}body.toc2{padding-top:90px;text-rendering:optimizeLegibility}#content #toc{border-style:solid;border-width:1px;border-color:#d7d7d7;margin-bottom:1.25em;padding:1.25em;background:#f1f1f1;-webkit-border-radius:4px;border-radius:4px}#content #toc>:first-child{margin-top:0}#content #toc>:last-child{margin-bottom:0}#footer{padding-bottom:2rem}#footer #footer-text{padding:2rem 0;border-top:1px solid #efefed}#footer-text{color:rgba(0,0,0,0.6);line-height:1.44}.sect1{padding-bottom:0.625em}.sect1+.sect1{border-top:1px solid #efefed}#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;margin-top:0.1rem;display:block;visibility:hidden;text-align:center;font-weight:normal;color:rgba(0,0,0,0.2)}#content h1>a.anchor:hover,h2>a.anchor:hover,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4>a.anchor:hover,h5>a.anchor:hover,h6>a.anchor:hover{color:#097dff;text-decoration:none}#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\0023";font-size:0.85em;display:block;padding-top:0.1em}#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#000;text-decoration:none}#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#262321}.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:Karla, sans-serif;font-size:1rem}table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0;padding:0.6rem 0}table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}.admonitionblock>table td.icon{text-align:center;vertical-align:top;padding-top:0.8em;width:80px}.admonitionblock>table td.icon img{max-width:initial}.admonitionblock>table td.icon .title{font-weight:bold;font-family:Montserrat, sans-serif;text-transform:uppercase}.admonitionblock>table td.content{padding-left:0em;padding-right:1.25em;border-left:1px solid #ddddd8}.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}.exampleblock>.content{border-style:solid;border-width:0;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#f1f1f1;border-radius:4px}.exampleblock>.content>:first-child{margin-top:0}.exampleblock>.content>:last-child{margin-bottom:0}.sidebarblock{border-style:solid;border-width:0;border-color:#d7d7d7;margin-bottom:1.25em;padding:1.25em;background:#f1f1f1;border-radius:4px;overflow:scroll}.sidebarblock>:first-child{margin-top:0}.sidebarblock>:last-child{margin-bottom:0}.sidebarblock>.content>.title{color:#0b0a0a;margin-top:0;text-align:center}.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#282c33;color:#e6e1dc;border-radius:4px}.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#282c33;color:#e6e1dc}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class],.listingblock pre:not(.highlight){padding:1em 1.5rem;font-size:0.8125em}.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto}.literalblock.output pre{color:whitesmoke;background-color:rgba(0,0,0,0.9)}.listingblock{white-space:nowrap}.listingblock pre.highlightjs{padding:0.2rem 0}.listingblock pre.highlightjs>code{padding:1em 1.5rem;border-radius:4px}.listingblock>.content{position:relative}.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:0.8em;font-weight:bold;top:0.425rem;right:0.5rem;line-height:1;text-transform:uppercase;color:#999}.listingblock code[data-lang]:before{display:block}.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:0.5em;color:#999}.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}table.pyhltable td.code{padding-left:.75em;padding-right:0}pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}pre.pygments .lineno{display:block;margin-right:.25em}table.pyhltable .linenodiv{background:none !important;padding-right:0 !important}.quoteblock{margin:0 1em 1.25em 1.5em;display:block;text-align:left;padding-left:20px}.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,0.85);line-height:1.75;letter-spacing:0}.quoteblock blockquote{margin:0;padding:0;border:0;position:relative}.quoteblock blockquote:before{content:"\201c";font-size:2.75em;font-weight:bold;line-height:0.6em;margin-left:0em;margin-right:1rem;margin-top:0.8rem;color:rgba(0,0,0,0.1);position:absolute;top:0;left:-30px}.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}.quoteblock .attribution{margin-right:0.5ex}.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:0.5em 0;border-left:3px solid rgba(0,0,0,0.6)}.quoteblock .quoteblock blockquote{padding:0 0 0 0.75em}.quoteblock .quoteblock blockquote:before{display:none}.verseblock{margin:0 1em 1.25em 0;background-color:#f1f1f1;padding:1rem 1.4rem;border-radius:4px}.verseblock pre{font-family:Monaco, Menlo, Consolas, "Courier New", monospace;font-size:0.9rem;color:rgba(0,0,0,0.85);font-weight:300;text-rendering:optimizeLegibility}.verseblock pre strong{font-weight:400}.verseblock .attribution{margin-top:1.25rem;margin-left:0.5ex}.quoteblock .attribution,.verseblock .attribution{font-size:0.9375em;line-height:1.45;font-style:italic}.quoteblock .attribution br,.verseblock .attribution br{display:none}.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-0.025em;color:rgba(0,0,0,0.6)}.quoteblock.abstract{margin:0 0 1.25em 0;display:block}.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}table.tableblock{max-width:100%;border-collapse:separate;overflow-x:scroll}table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}table.tableblock,th.tableblock,td.tableblock{border:0 solid #cacaca;background:white}table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}table.frame-all{border-width:1px}table.frame-sides{border-width:0 1px}table.frame-topbot{border-width:1px 0}th.halign-left,td.halign-left{text-align:left}th.halign-right,td.halign-right{text-align:right}th.halign-center,td.halign-center{text-align:center}th.valign-top,td.valign-top{vertical-align:top}th.valign-bottom,td.valign-bottom{vertical-align:bottom}th.valign-middle,td.valign-middle{vertical-align:middle}table thead th,table tfoot th{font-weight:bold}tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:#34302d;font-weight:bold}p.tableblock>code:only-child{background:none;padding:0}p.tableblock{font-size:1em}td>div.verse{white-space:pre}ol{margin-left:1.75em}ul li ol{margin-left:1.5em}dl dd{margin-left:1.125em}dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:0.625em}ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}ul.unstyled,ol.unnumbered,ul.checklist{margin-left:0.625em}ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:0.85em}ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}ul.inline{margin:0 auto 0.625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}ul.inline>li>*{display:block}.unstyled dl dt{font-weight:normal;font-style:normal}ol.arabic{list-style-type:decimal}ol.decimal{list-style-type:decimal-leading-zero}ol.loweralpha{list-style-type:lower-alpha}ol.upperalpha{list-style-type:upper-alpha}ol.lowerroman{list-style-type:lower-roman}ol.upperroman{list-style-type:upper-roman}ol.lowergreek{list-style-type:lower-greek}.hdlist>table,.colist>table{border:0;background:none}.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}td.hdlist1,td.hdlist2{vertical-align:top;padding:0 0.625em}td.hdlist1{font-weight:bold;padding-bottom:1.25em}.literalblock+.colist,.listingblock+.colist{margin-top:-0.5em}.colist>table tr>td:first-of-type{padding:0 0.75em;line-height:1}.colist>table tr>td:first-of-type img{max-width:initial}.colist>table tr>td:last-of-type{padding:0.25em 0}.thumb,.th{line-height:0;display:inline-block;border:solid 4px white;-webkit-box-shadow:0 0 0 1px #dddddd;box-shadow:0 0 0 1px #dddddd}.imageblock.left,.imageblock[style*="float: left"]{margin:0.25em 0.625em 1.25em 0}.imageblock.right,.imageblock[style*="float: right"]{margin:0.25em 0 1.25em 0.625em}.imageblock>.title{margin-bottom:0}.imageblock.thumb,.imageblock.th{border-width:6px}.imageblock.thumb>.title,.imageblock.th>.title{padding:0 0.125em}.image.left,.image.right{margin-top:0.25em;margin-bottom:0.25em;display:inline-block;line-height:0}.image.left{margin-right:0.625em}.image.right{margin-left:0.625em}a.image{text-decoration:none;display:inline-block}a.image object{pointer-events:none}sup.footnote,sup.footnoteref{font-size:0.875em;position:static;vertical-align:super}sup.footnote a,sup.footnoteref a{text-decoration:none}sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}#footnotes{padding-top:0.75em;padding-bottom:0.75em;margin-bottom:0.625em}#footnotes hr{width:20%;min-width:6.25em;margin:-0.25em 0 0.75em 0;border-width:1px 0 0 0}#footnotes .footnote{padding:0 0.375em 0 0.225em;line-height:1.3334;font-size:0.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:0.2em}#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}#footnotes .footnote:last-of-type{margin-bottom:0}#content #footnotes{margin-top:-0.625em;margin-bottom:0;padding:0.75em 0}.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}.gist .file-data>table td.line-data{width:99%}div.unbreakable{page-break-inside:avoid}.big{font-size:larger}.small{font-size:smaller}.underline{text-decoration:underline}.overline{text-decoration:overline}.line-through{text-decoration:line-through}.aqua{color:#00bfbf}.aqua-background{background-color:#00fafa}.black{color:black}.black-background{background-color:black}.blue{color:#0000bf}.blue-background{background-color:#0000fa}.fuchsia{color:#bf00bf}.fuchsia-background{background-color:#fa00fa}.gray{color:#606060}.gray-background{background-color:#7d7d7d}.green{color:#006000}.green-background{background-color:#007d00}.lime{color:#00bf00}.lime-background{background-color:#00fa00}.maroon{color:#600000}.maroon-background{background-color:#7d0000}.navy{color:#000060}.navy-background{background-color:#00007d}.olive{color:#606000}.olive-background{background-color:#7d7d00}.purple{color:#600060}.purple-background{background-color:#7d007d}.red{color:#bf0000}.red-background{background-color:#fa0000}.silver{color:#909090}.silver-background{background-color:#bcbcbc}.teal{color:#006060}.teal-background{background-color:#007d7d}.white{color:#bfbfbf}.white-background{background-color:#fafafa}.yellow{color:#bfbf00}.yellow-background{background-color:#fafa00}span.icon>.fa{cursor:default}.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;cursor:default}.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#3f6a22}.admonitionblock td.icon .icon-tip:before{content:"\f0eb";color:#0077b9}.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#d88400}.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}.conum[data-value]{display:inline-block;color:#000 !important;background-color:#ffe157;-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:0.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans", "DejaVu Sans", sans-serif;font-style:normal;font-weight:bold}.conum[data-value] *{color:#fff !important}.conum[data-value]+b{display:none}.conum[data-value]:after{content:attr(data-value)}pre .conum[data-value]{position:relative;top:0;color:#000 !important;background-color:#ffe157;font-size:12px}b.conum *{color:inherit !important}.conum:not([data-value]):empty{display:none}.admonitionblock{background-color:#ecf1e8;padding:0.8em 0;margin:30px 0;width:auto;border-radius:4px;overflow-x:scroll}.admonitionblock.important{border-left:0px solid #e20000;background-color:#f9ebeb}.admonitionblock.warning{border-left:0px solid #d88400;background-color:#fff9e4}.admonitionblock.tip{border-left:0px solid #0077b9;background-color:#e9f1f6}.admonitionblock.caution{border-left:0px solid #e20000;background-color:#f9ebeb}.admonitionblock .exampleblock>.content{border:0 none;background-color:#fff}#toc a:hover{text-decoration:underline}.admonitionblock>table{margin-bottom:0}.admonitionblock>table td.content{border-left:none}@media print{#tocbot a.toc-link.node-name--H4{display:none}}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 200ms ease-in-out}.is-collapsed{max-height:0}div.back-action,#toc.toc2 div.back-action{padding:0.8rem 0 0 0}div.back-action a,#toc.toc2 div.back-action a{position:relative;display:inline-block;padding:0.6rem 1.2rem;padding-left:35px}div.back-action a span,#toc.toc2 div.back-action a span{position:absolute;left:5px;top:5px;display:block;color:#333;height:26px;width:26px;border-radius:13px}div.back-action a i,#toc.toc2 div.back-action a i{position:absolute;top:5px;left:5px}div.back-action a:hover span,#toc.toc2 div.back-action a:hover span{color:#000}#tocbot.desktop-toc{padding-top:0.8rem}#header-spring{position:absolute;text-rendering:optimizeLegibility;top:0;left:0;right:0;height:90px;margin:0 1rem;padding:0 1rem;border-bottom:1px solid #ddddd8;border-top:3px solid #6BB344}#header-spring h1{margin:0;padding:0;font-size:22px;text-align:left;line-height:86px;padding-left:0.6rem}#header-spring h1 svg{width:200px}#header-spring h1 svg .st0{fill:#6BB344}#header-spring h1 svg .st2{fill:#444}body.book #header-spring{position:relative;top:auto;left:auto;right:auto;margin:0}body.book #header>h1:only-child{border:0 none;padding-bottom:1.2rem;font-size:1.8rem}body.book #header,body.book #content,body.book #footnotes,body.book #footer{margin:0 auto}body.toc2 #header-spring{position:absolute;left:0;right:0;top:0}body.toc2 #header>h1:only-child{font-size:2.2rem}body.toc2 #header,body.toc2 #content,body.toc2 #footnotes,body.toc2 #footer{margin:0 auto}body.toc2 #content{padding-top:2rem}#header,#content,#footnotes,#footer{width:100%;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:0.9375em;padding-right:0.9375em}#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}#header:after,#content:after,#footnotes:after,#footer:after{clear:both}#content{margin-top:1.25em}#content:before{content:none}#header>h1:first-child{margin-top:2.55rem;margin-bottom:0.5em;margin-bottom:0.5em}#header>h1:first-child+#toc{margin-top:8px;border-top:0 none}#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:0;padding-bottom:2.25em;padding-left:0.25em;color:rgba(0,0,0,0.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}#header .details span:first-child{margin-left:-0.125em}#header .details span.email a{color:rgba(0,0,0,0.85)}#header .details br{display:none}#header .details br+span:before{content:"\00a0\2013\00a0"}#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,0.85)}#header .details br+span#revremark:before{content:"\00a0|\00a0"}#header #revnumber{text-transform:capitalize}#header #revnumber:after{content:"\00a0"}#content>h1:first-child:not([class]){color:rgba(0,0,0,0.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1.5rem;margin-bottom:1.25rem}h1{font-size:2.2rem;letter-spacing:-1px}h1,h2,h3,h4,h5,h6{font-weight:normal;font-family:Montserrat, Arial, Helvetica, sans-serif}h1:focus,h2:focus,h3:focus,h4:focus,h5:focus,h6:focus{box-shadow:none;outline:none}h2,h3,h4,h5,h6{padding:.8rem 0 .4rem}h1{font-size:1.75em}h2{font-size:1.6rem;letter-spacing:-1px}h3{font-size:1.5rem}h4{font-size:1.4rem}h5{font-size:1.3rem}h6{font-size:1.2rem}pre.highlight{background:#232323;color:#e6e1dc;border-radius:4px}pre.highlight code{color:#e6e1dc}pre.highlight a,#toc.toc2 a{color:#000;font-size:1rem}pre.highlight ul.sectlevel1,#toc.toc2 ul.sectlevel1{padding-left:0.2rem}pre.highlight ul.sectlevel1 li,#toc.toc2 ul.sectlevel1 li{line-height:1.4rem}::selection{background-color:#d1ff79}.literalblock pre::selection,.listingblock pre[class="highlight"]::selection,.highlight::selection,pre::selection,.highlight code::selection,.highlight code span::selection{background:rgba(255,255,255,0.2) !important}body.book #header{margin-bottom:2rem}body.toc2 #header{margin-bottom:0}.desktop-toc{display:none}.admonitionblock td.icon{display:none}.admonitionblock>table td.content{padding-left:1.25em}@media only screen and (min-width: 768px){#toctitle{font-size:1.375em}.sect1{padding-bottom:1.25em}.mobile-toc{display:none}.desktop-toc{display:block}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:0.90625em}.admonitionblock td.icon{display:table-cell}.admonitionblock>table td.content{padding-left:0}body.toc2{padding-right:0}body.toc2 #toc.toc2{position:absolute;margin-top:0 !important;width:15em;top:0;border-top-width:0 !important;border-bottom-width:0 !important;margin-left:-15.9375em;z-index:1000;padding:0 1em 1.25em 0em;overflow:auto}body.toc2 #toc.toc2 #toctitle{margin-top:0;margin-bottom:0.8rem;font-size:1.2em}body.toc2 #toc.toc2>ul{font-size:0.9em;margin-bottom:0}body.toc2 #toc.toc2 ul ul{margin-left:0;padding-left:1em}body.toc2 #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:0.5em;margin-bottom:0.5em}body.toc2 #header,body.toc2 #content,body.toc2 #footnotes,body.toc2 #footer{padding-left:15.9375em;max-width:none}body.book #header-spring h1{max-width:1400px;margin:0 auto}body.book #header,body.book #content,body.book #footnotes,body.book #footer{max-width:1400px}body.is-position-fixed #toc.toc2{position:fixed;height:100%}h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}h1{font-size:1.75em}h2{font-size:1.6em}h3,#toctitle,.sidebarblock>.content>.title{font-size:1.5em}h4{font-size:1.4em}h5{font-size:1.2em}h6{font-size:1.2em}#tocbot a.toc-link.node-name--H1{font-style:italic}#tocbot ol{margin:0;padding:0;padding-left:0.6rem}#tocbot ol li{list-style:none;padding:0 0;margin:0;display:block}#tocbot{z-index:999}#tocbot .toc-link{position:relative;display:block;z-index:999;padding-right:5px;padding-top:4px;padding-bottom:4px}#tocbot .is-active-link{padding-right:3px;border-right:3px solid #6BB344}}@media only screen and (min-width: 768px){#tocbot>ul.toc-list{margin-bottom:0.5em;margin-left:0.125em}#tocbot ul.sectlevel0,#tocbot a.toc-link.node-name--H1+ul{padding-left:0}#tocbot a.toc-link{height:100%}.is-collapsible{max-height:3000px;overflow:hidden}.is-collapsed{max-height:0}.is-active-link{font-weight:700}}@media only screen and (min-width: 768px){body.toc2 #header,body.toc2 #content,body.toc2 #footer{background-repeat:repeat-y;background-position:14em 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDE0NUNENzNGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDE0NUNENzRGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEMTQ1Q0Q3MUYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEMTQ1Q0Q3MkYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjmGxxYAAAAGUExURd3d2AAAAJlCnKAAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=)}}@media only screen and (min-width: 1280px){body.toc2{padding-right:0}body.toc2 #toc.toc2{width:25em;left:auto;margin-left:-26.9375em}body.toc2 #toc.toc2 #toctitle{font-size:1.375em}body.toc2 #toc.toc2>ul{font-size:0.95em}body.toc2 #toc.toc2 ul ul{padding-left:1.25em}body.toc2 body.toc2.toc-right{padding-left:0;padding-right:20em}body.toc2 #header,body.toc2 #content,body.toc2 #footnotes,body.toc2 #footer{padding-left:26.9375em;max-width:1400px}body.toc2 #header-spring h1{margin:0 auto;max-width:1400px}.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:0.8125em}body.toc2 #header,body.toc2 #content,body.toc2 #footer{background-repeat:repeat-y;background-position:24em 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDE0NUNENzNGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDE0NUNENzRGMTVGMTFFODk5RjI5ODk3QURGRjcxMkEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEMTQ1Q0Q3MUYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEMTQ1Q0Q3MkYxNUYxMUU4OTlGMjk4OTdBREZGNzEyQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjmGxxYAAAAGUExURd3d2AAAAJlCnKAAAAAMSURBVHjaYmAACDAAAAIAAU9tWeEAAAAASUVORK5CYII=)}} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/favicon.ico b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/favicon.ico new file mode 100644 index 00000000..1a4956e6 Binary files /dev/null and b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/favicon.ico differ diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/highlight.min.js b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/highlight.min.js new file mode 100644 index 00000000..dcbbb4c7 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/highlight.min.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.13.1 | BSD3 License | git.io/hljslicense */ +!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=M.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function c(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function u(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function c(e){l+=""}function u(e){("start"===e.event?o:c)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(c);do u(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),u(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function l(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):B(a.k).forEach(function(e){c(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.endSameAsBegin&&(a.e=a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return s("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var u=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=u.length?t(u.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e){return new RegExp(e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")}function c(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=o(n.c[t].bR.exec(e)[0])),n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function s(e,n){return!a&&r(n.iR,e)}function p(e,n){var t=R.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function d(e,n,t,r){var a=r?"":j.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=p(E,r),e?(M+=e[1],a+=d(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function b(){var e="string"==typeof E.sL;if(e&&!L[E.sL])return n(k);var t=e?f(E.sL,k,!0,B[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(B[E.sL]=t.top),d(t.language,t.value,!1,!0)}function v(){y+=null!=E.sL?b():h(),k=""}function m(e){y+=e.cN?d(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function N(e,n){if(k+=e,null==n)return v(),0;var t=c(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),v(),t.rB||t.eB||(k=n)),m(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),v(),a.eE&&(k=n));do E.cN&&(y+=I),E.skip||E.sL||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),m(r.starts,"")),a.rE?0:n.length}if(s(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var R=w(e);if(!R)throw new Error('Unknown language: "'+e+'"');l(R);var x,E=i||R,B={},y="";for(x=E;x!==R;x=x.parent)x.cN&&(y=d(x.cN,"",!0)+y);var k="",M=0;try{for(var C,A,S=0;;){if(E.t.lastIndex=S,C=E.t.exec(t),!C)break;A=N(t.substring(S,C.index),C[0]),S=C.index+A}for(N(t.substr(S)),x=E;x.parent;x=x.parent)x.cN&&(y+=I);return{r:M,value:y,language:e,top:E}}catch(O){if(O.message&&-1!==O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function g(e,t){t=t||j.languages||B(L);var r={r:0,value:n(e)},a=r;return t.filter(w).filter(x).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return j.tabReplace||j.useBR?e.replace(C,function(e,n){return j.useBR&&"\n"===e?"
":j.tabReplace?n.replace(/\t/g,j.tabReplace):""}):e}function d(e,n,t){var r=n?y[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function h(e){var n,t,r,o,s,l=i(e);a(l)||(j.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=l?f(l,s,!0):g(s),t=c(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=u(t,c(o),s)),r.value=p(r.value),e.innerHTML=r.value,e.className=d(e.className,l,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){j=o(j,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,h)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=L[n]=t(e);r.aliases&&r.aliases.forEach(function(e){y[e]=n})}function R(){return B(L)}function w(e){return e=(e||"").toLowerCase(),L[e]||L[y[e]]}function x(e){var n=w(e);return n&&!n.disableAutodetect}var E=[],B=Object.keys,L={},y={},k=/^(no-?highlight|plain|text)$/i,M=/\blang(?:uage)?-([\w-]+)\b/i,C=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,I="
",j={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=h,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.autoDetection=x,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\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/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|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)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{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",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("dockerfile",function(e){return{aliases:["docker"],cI:!0,k:"from maintainer expose env arg user onbuild stopsignal",c:[e.HCM,e.ASM,e.QSM,e.NM,{bK:"run cmd entrypoint volume add copy workdir label healthcheck shell",starts:{e:/[^\\]\n/,sL:"bash"}}],i:")?[^\s\(]+(\s+[^\s\(]+)\s*=/,r:5,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"type",b://,k:"reified",r:0},{cN:"params",b:/\(/,e:/\)/,endsParent:!0,k:t,r:0,c:[{b:/:/,e:/[=,\/]/,eW:!0,c:[{cN:"type",b:e.UIR},e.CLCM,e.CBCM],r:0},e.CLCM,e.CBCM,s,l,c,e.CNM]},e.CBCM]},{cN:"class",bK:"class interface trait",e:/[:\{(]|$/,eE:!0,i:"extends implements",c:[{bK:"public protected internal private constructor"},e.UTM,{cN:"type",b://,eB:!0,eE:!0,r:0},{cN:"type",b:/[,:]\s*/,e:/[<\(,]|$/,eB:!0,rE:!0},s,l]},c,{cN:"meta",b:"^#!/usr/bin/env",e:"$",i:"\n"},o]}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="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",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("properties",function(r){var t="[ \\t\\f]*",e="[ \\t\\f]+",s="("+t+"[:=]"+t+"|"+e+")",n="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",c={e:s,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[r.C("^\\s*[!#]","$"),{b:n+s,rB:!0,c:[{cN:"attr",b:n,endsParent:!0,r:0}],starts:c},{b:a+s,rB:!0,r:0,c:[{cN:"meta",b:a,endsParent:!0,r:0}],starts:c},{cN:"attr",r:0,b:a+t+"$"}]}});hljs.registerLanguage("diff",function(e){return{aliases:["patch"],c:[{cN:"meta",r:10,v:[{b:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"comment",v:[{b:/Index: /,e:/$/},{b:/={3,}/,e:/$/},{b:/^\-{3}/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+{3}/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"addition",b:"^\\!",e:"$"}]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});hljs.registerLanguage("asciidoc",function(e){return{aliases:["adoc"],c:[e.C("^/{4,}\\n","\\n/{4,}$",{r:10}),e.C("^//","$",{r:0}),{cN:"title",b:"^\\.\\w.*$"},{b:"^[=\\*]{4,}\\n",e:"\\n^[=\\*]{4,}$",r:10},{cN:"section",r:10,v:[{b:"^(={1,5}) .+?( \\1)?$"},{b:"^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$"}]},{cN:"meta",b:"^:.+?:",e:"\\s",eE:!0,r:10},{cN:"meta",b:"^\\[.+?\\]$",r:0},{cN:"quote",b:"^_{4,}\\n",e:"\\n_{4,}$",r:10},{cN:"code",b:"^[\\-\\.]{4,}\\n",e:"\\n[\\-\\.]{4,}$",r:10},{b:"^\\+{4,}\\n",e:"\\n\\+{4,}$",c:[{b:"<",e:">",sL:"xml",r:0}],r:10},{cN:"bullet",b:"^(\\*+|\\-+|\\.+|[^\\n]+?::)\\s+"},{cN:"symbol",b:"^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+",r:10},{cN:"strong",b:"\\B\\*(?![\\*\\s])",e:"(\\n{2}|\\*)",c:[{b:"\\\\*\\w",r:0}]},{cN:"emphasis",b:"\\B'(?!['\\s])",e:"(\\n{2}|')",c:[{b:"\\\\'\\w",r:0}],r:0},{cN:"emphasis",b:"_(?![_\\s])",e:"(\\n{2}|_)",r:0},{cN:"string",v:[{b:"``.+?''"},{b:"`.+?'"}]},{cN:"code",b:"(`.+?`|\\+.+?\\+)",r:0},{cN:"code",b:"^[ \\t]",e:"$",r:0},{b:"^'{3,}[ \\t]*$",r:10},{b:"(link:)?(http|https|ftp|file|irc|image:?):\\S+\\[.*?\\]",rB:!0,c:[{b:"(link|image:?):",r:0},{cN:"link",b:"\\w",e:"[^\\[]+",r:0},{cN:"string",b:"\\[",e:"\\]",eB:!0,eE:!0,r:0}],r:10}]}});hljs.registerLanguage("aspectj",function(e){var t="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else extends implements break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws privileged aspectOf adviceexecution proceed cflowbelow cflow initialization preinitialization staticinitialization withincode target within execution getWithinTypeName handler thisJoinPoint thisJoinPointStaticPart thisEnclosingJoinPointStaticPart declare parents warning error soft precedence thisAspectInstance",i="get set args call";return{k:t,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"aspect",e:/[{;=]/,eE:!0,i:/[:;"\[\]]/,c:[{bK:"extends implements pertypewithin perthis pertarget percflowbelow percflow issingleton"},e.UTM,{b:/\([^\)]*/,e:/[)]+/,k:t+" "+i,eE:!1}]},{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,r:0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"pointcut after before around throwing returning",e:/[)]/,eE:!1,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",rB:!0,c:[e.UTM]}]},{b:/[:]/,rB:!0,e:/[{;]/,r:0,eE:!1,k:t,i:/["\[\]]/,c:[{b:e.UIR+"\\s*\\(",k:t+" "+i,r:0},e.QSM]},{bK:"new throw",r:0},{cN:"function",b:/\w+ +\w+(\.)?\w+\s*\([^\)]*\)\s*((throws)[\w\s,]+)?[\{;]/,rB:!0,e:/[{;=]/,k:t,eE:!0,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,r:0,k:t,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("gradle",function(e){return{cI:!0,k:{keyword:"task project allprojects subprojects artifacts buildscript configurations dependencies repositories sourceSets description delete from into include exclude source classpath destinationDir includes options sourceCompatibility targetCompatibility group flatDir doLast doFirst flatten todir fromdir ant def abstract break case catch continue default do else extends final finally for if implements instanceof native new private protected public return static switch synchronized throw throws transient try volatile while strictfp package import false null super this true antlrtask checkstyle codenarc copy boolean byte char class double float int interface long short void compile runTime file fileTree abs any append asList asWritable call collect compareTo count div dump each eachByte eachFile eachLine every find findAll flatten getAt getErr getIn getOut getText grep immutable inject inspect intersect invokeMethods isCase join leftShift minus multiply newInputStream newOutputStream newPrintWriter newReader newWriter next plus pop power previous print println push putAt read readBytes readLines reverse reverseEach round size sort splitEachLine step subMap times toInteger toList tokenize upto waitForOrKill withPrintWriter withReader withStream withWriter withWriterAppend write writeLine"},c:[e.CLCM,e.CBCM,e.ASM,e.QSM,e.NM,e.RM]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("sql",function(e){var t=e.C("--","$");return{cI:!0,i:/[<>{}*]/,c:[{bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment with",e:/;/,eW:!0,l:/[\w\.]+/,k:{keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias allocate allow alter always analyze ancillary and any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second section securefile security seed segment select self sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp varchar varying void"},c:[{cN:"string",b:"'",e:"'",c:[e.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[e.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[e.BE]},e.CNM,e.CBCM,t,e.HCM]},e.CBCM,t,e.HCM]}});hljs.registerLanguage("go",function(e){var t={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{aliases:["golang"],k:t,i:"",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}); \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/a11y-dark.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/a11y-dark.min.css new file mode 100644 index 00000000..b93b742a --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/a11y-dark.min.css @@ -0,0 +1,99 @@ +/* a11y-dark theme */ +/* Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css */ +/* @author: ericwbailey */ + +/* Comment */ +.hljs-comment, +.hljs-quote { + color: #d4d0ab; +} + +/* Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #ffa07a; +} + +/* Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f5ab35; +} + +/* Yellow */ +.hljs-attribute { + color: #ffd700; +} + +/* Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #abe338; +} + +/* Blue */ +.hljs-title, +.hljs-section { + color: #00e0e0; +} + +/* Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #dcc6e0; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2b2b2b; + color: #f8f8f2; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +@media screen and (-ms-high-contrast: active) { + .hljs-addition, + .hljs-attribute, + .hljs-built_in, + .hljs-builtin-name, + .hljs-bullet, + .hljs-comment, + .hljs-link, + .hljs-literal, + .hljs-meta, + .hljs-number, + .hljs-params, + .hljs-string, + .hljs-symbol, + .hljs-type, + .hljs-quote { + color: highlight; + } + + .hljs-keyword, + .hljs-selector-tag { + font-weight: bold; + } +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/an-old-hope.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/an-old-hope.min.css new file mode 100644 index 00000000..a6d56f4b --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/an-old-hope.min.css @@ -0,0 +1,89 @@ +/* + +An Old Hope – Star Wars Syntax (c) Gustavo Costa +Original theme - Ocean Dark Theme – by https://github.com/gavsiu +Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom + +*/ + +/* Death Star Comment */ +.hljs-comment, +.hljs-quote +{ + color: #B6B18B; +} + +/* Darth Vader */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion +{ + color: #EB3C54; +} + +/* Threepio */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link +{ + color: #E7CE56; +} + +/* Luke Skywalker */ +.hljs-attribute +{ + color: #EE7C2B; +} + +/* Obi Wan Kenobi */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition +{ + color: #4FB4D7; +} + +/* Yoda */ +.hljs-title, +.hljs-section +{ + color: #78BB65; +} + +/* Mace Windu */ +.hljs-keyword, +.hljs-selector-tag +{ + color: #B45EA4; +} + +/* Millenium Falcon */ +.hljs +{ + display: block; + overflow-x: auto; + background: #1C1D21; + color: #c0c5ce; + padding: 0.5em; +} + +.hljs-emphasis +{ + font-style: italic; +} + +.hljs-strong +{ + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-dark-reasonable.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-dark-reasonable.min.css new file mode 100644 index 00000000..fd41c996 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-dark-reasonable.min.css @@ -0,0 +1,77 @@ +/* + +Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage + +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + line-height: 1.3em; + color: #abb2bf; + background: #282c34; + border-radius: 5px; +} +.hljs-keyword, .hljs-operator { + color: #F92672; +} +.hljs-pattern-match { + color: #F92672; +} +.hljs-pattern-match .hljs-constructor { + color: #61aeee; +} +.hljs-function { + color: #61aeee; +} +.hljs-function .hljs-params { + color: #A6E22E; +} +.hljs-function .hljs-params .hljs-typing { + color: #FD971F; +} +.hljs-module-access .hljs-module { + color: #7e57c2; +} +.hljs-constructor { + color: #e2b93d; +} +.hljs-constructor .hljs-string { + color: #9CCC65; +} +.hljs-comment, .hljs-quote { + color: #b18eb1; + font-style: italic; +} +.hljs-doctag, .hljs-formula { + color: #c678dd; +} +.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst { + color: #e06c75; +} +.hljs-literal { + color: #56b6c2; +} +.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string { + color: #98c379; +} +.hljs-built_in, .hljs-class .hljs-title { + color: #e6c07b; +} +.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number { + color: #d19a66; +} +.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title { + color: #61aeee; +} +.hljs-emphasis { + font-style: italic; +} +.hljs-strong { + font-weight: bold; +} +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-dark.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-dark.min.css new file mode 100644 index 00000000..1616aafe --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-dark.min.css @@ -0,0 +1,96 @@ +/* + +Atom One Dark by Daniel Gamage +Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax + +base: #282c34 +mono-1: #abb2bf +mono-2: #818896 +mono-3: #5c6370 +hue-1: #56b6c2 +hue-2: #61aeee +hue-3: #c678dd +hue-4: #98c379 +hue-5: #e06c75 +hue-5-2: #be5046 +hue-6: #d19a66 +hue-6-2: #e6c07b + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #abb2bf; + background: #282c34; +} + +.hljs-comment, +.hljs-quote { + color: #5c6370; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #c678dd; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e06c75; +} + +.hljs-literal { + color: #56b6c2; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #98c379; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #e6c07b; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #d19a66; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #61aeee; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-light.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-light.min.css new file mode 100644 index 00000000..d5bd1d2a --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/atom-one-light.min.css @@ -0,0 +1,96 @@ +/* + +Atom One Light by Daniel Gamage +Original One Light Syntax theme from https://github.com/atom/one-light-syntax + +base: #fafafa +mono-1: #383a42 +mono-2: #686b77 +mono-3: #a0a1a7 +hue-1: #0184bb +hue-2: #4078f2 +hue-3: #a626a4 +hue-4: #50a14f +hue-5: #e45649 +hue-5-2: #c91243 +hue-6: #986801 +hue-6-2: #c18401 + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #383a42; + background: #fafafa; +} + +.hljs-comment, +.hljs-quote { + color: #a0a1a7; + font-style: italic; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-formula { + color: #a626a4; +} + +.hljs-section, +.hljs-name, +.hljs-selector-tag, +.hljs-deletion, +.hljs-subst { + color: #e45649; +} + +.hljs-literal { + color: #0184bb; +} + +.hljs-string, +.hljs-regexp, +.hljs-addition, +.hljs-attribute, +.hljs-meta-string { + color: #50a14f; +} + +.hljs-built_in, +.hljs-class .hljs-title { + color: #c18401; +} + +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-type, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-number { + color: #986801; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link, +.hljs-meta, +.hljs-selector-id, +.hljs-title { + color: #4078f2; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-link { + text-decoration: underline; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/dracula.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/dracula.min.css new file mode 100644 index 00000000..d591db68 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/dracula.min.css @@ -0,0 +1,76 @@ +/* + +Dracula Theme v1.2.0 + +https://github.com/zenorocha/dracula-theme + +Copyright 2015, All rights reserved + +Code licensed under the MIT license +http://zenorocha.mit-license.org + +@author Éverton Ribeiro +@author Zeno Rocha + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #282a36; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-section, +.hljs-link { + color: #8be9fd; +} + +.hljs-function .hljs-keyword { + color: #ff79c6; +} + +.hljs, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-string, +.hljs-title, +.hljs-name, +.hljs-type, +.hljs-attribute, +.hljs-symbol, +.hljs-bullet, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #f1fa8c; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #6272a4; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-title, +.hljs-section, +.hljs-doctag, +.hljs-type, +.hljs-name, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/github.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/github.min.css new file mode 100644 index 00000000..791932b8 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/github.min.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/monokai-sublime.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/monokai-sublime.min.css new file mode 100644 index 00000000..2864170d --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/monokai-sublime.min.css @@ -0,0 +1,83 @@ +/* + +Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #23241f; +} + +.hljs, +.hljs-tag, +.hljs-subst { + color: #f8f8f2; +} + +.hljs-strong, +.hljs-emphasis { + color: #a8a8a2; +} + +.hljs-bullet, +.hljs-quote, +.hljs-number, +.hljs-regexp, +.hljs-literal, +.hljs-link { + color: #ae81ff; +} + +.hljs-code, +.hljs-title, +.hljs-section, +.hljs-selector-class { + color: #a6e22e; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-name, +.hljs-attr { + color: #f92672; +} + +.hljs-symbol, +.hljs-attribute { + color: #66d9ef; +} + +.hljs-params, +.hljs-class .hljs-title { + color: #f8f8f2; +} + +.hljs-string, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-id, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-variable { + color: #e6db74; +} + +.hljs-comment, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/monokai.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/monokai.min.css new file mode 100644 index 00000000..775d53f9 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/monokai.min.css @@ -0,0 +1,70 @@ +/* +Monokai style - ported by Luigi Maselli - http://grigio.org +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #272822; color: #ddd; +} + +.hljs-tag, +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-strong, +.hljs-name { + color: #f92672; +} + +.hljs-code { + color: #66d9ef; +} + +.hljs-class .hljs-title { + color: white; +} + +.hljs-attribute, +.hljs-symbol, +.hljs-regexp, +.hljs-link { + color: #bf79db; +} + +.hljs-string, +.hljs-bullet, +.hljs-subst, +.hljs-title, +.hljs-section, +.hljs-emphasis, +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-addition, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #a6e22e; +} + +.hljs-comment, +.hljs-quote, +.hljs-deletion, +.hljs-meta { + color: #75715e; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal, +.hljs-doctag, +.hljs-title, +.hljs-section, +.hljs-type, +.hljs-selector-id { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/solarized-light.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/solarized-light.min.css new file mode 100644 index 00000000..fdcfcc72 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/solarized-light.min.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} + +.hljs-comment, +.hljs-quote { + color: #93a1a1; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/zenburn.min.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/zenburn.min.css new file mode 100644 index 00000000..07be5020 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/highlight/styles/zenburn.min.css @@ -0,0 +1,80 @@ +/* + +Zenburn style from voldmar.ru (c) Vladimir Epifanov +based on dark.css by Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #3f3f3f; + color: #dcdcdc; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag { + color: #e3ceab; +} + +.hljs-template-tag { + color: #dcdcdc; +} + +.hljs-number { + color: #8cd0d3; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute { + color: #efdcbc; +} + +.hljs-literal { + color: #efefaf; +} + +.hljs-subst { + color: #8f8f8f; +} + +.hljs-title, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: #efef8f; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #dca3a3; +} + +.hljs-deletion, +.hljs-string, +.hljs-built_in, +.hljs-builtin-name { + color: #cc9393; +} + +.hljs-addition, +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #7f9f7f; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/toc.js b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/toc.js new file mode 100644 index 00000000..a6e933bf --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/toc.js @@ -0,0 +1,107 @@ +var toctitle = document.getElementById('toctitle'); +var path = window.location.pathname; +if (toctitle != null) { + var oldtoc = toctitle.nextElementSibling; + var newtoc = document.createElement('div'); + newtoc.setAttribute('id', 'tocbot'); + newtoc.setAttribute('class', 'js-toc desktop-toc'); + oldtoc.setAttribute('class', 'mobile-toc'); + oldtoc.parentNode.appendChild(newtoc); + tocbot.init({ + contentSelector: '#content', + headingSelector: 'h1, h2, h3, h4, h5', + positionFixedSelector: 'body', + fixedSidebarOffset: 90, + smoothScroll: false + }); + if (!path.endsWith("index.html") && !path.endsWith("/")) { + var link = document.createElement("a"); + link.setAttribute("href", "index.html"); + link.innerHTML = " Back to index"; + var block = document.createElement("div"); + block.setAttribute('class', 'back-action'); + block.appendChild(link); + var toc = document.getElementById('toc'); + var next = document.getElementById('toctitle').nextElementSibling; + toc.insertBefore(block, next); + } +} + +var headerHtml = '
\n' + + '

\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '

\n' + + '
'; + +var header = document.createElement("div"); +header.innerHTML = headerHtml; +document.body.insertBefore(header, document.body.firstChild); \ No newline at end of file diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/tocbot/tocbot.css b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/tocbot/tocbot.css new file mode 100644 index 00000000..0632de23 --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/tocbot/tocbot.css @@ -0,0 +1 @@ +.toc{overflow-y:auto}.toc>.toc-list{overflow:hidden;position:relative}.toc>.toc-list li{list-style:none}.toc-list{margin:0;padding-left:10px}a.toc-link{color:currentColor;height:100%}.is-collapsible{max-height:1000px;overflow:hidden;transition:all 300ms ease-in-out}.is-collapsed{max-height:0}.is-position-fixed{position:fixed !important;top:0}.is-active-link{font-weight:700}.toc-link::before{background-color:#EEE;content:' ';display:inline-block;height:inherit;left:0;margin-top:-1px;position:absolute;width:2px}.is-active-link::before{background-color:#54BC4B} diff --git a/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/tocbot/tocbot.min.js b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/tocbot/tocbot.min.js new file mode 100644 index 00000000..943d8fdb --- /dev/null +++ b/spring-cloud-info/src/main/resources/static/docs/reference/htmlsingle/js/tocbot/tocbot.min.js @@ -0,0 +1 @@ +!function(e){function t(o){if(n[o])return n[o].exports;var l=n[o]={i:o,l:!1,exports:{}};return e[o].call(l.exports,l,l.exports,t),l.l=!0,l.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){(function(o){var l,i,s;!function(n,o){i=[],l=o(n),void 0!==(s="function"==typeof l?l.apply(t,i):l)&&(e.exports=s)}(void 0!==o?o:this.window||this.global,function(e){"use strict";function t(){for(var e={},t=0;te.fixedSidebarOffset?-1===n.className.indexOf(e.positionFixedClass)&&(n.className+=h+e.positionFixedClass):n.className=n.className.split(h+e.positionFixedClass).join("")}function s(t){var n=document.documentElement.scrollTop||f.scrollTop;e.positionFixedSelector&&i();var o,l=t;if(m&&null!==document.querySelector(e.tocSelector)&&l.length>0){d.call(l,function(t,i){if(t.offsetTop>n+e.headingsOffset+10){return o=l[0===i?i:i-1],!0}if(i===l.length-1)return o=l[l.length-1],!0});var s=document.querySelector(e.tocSelector).querySelectorAll("."+e.linkClass);u.call(s,function(t){t.className=t.className.split(h+e.activeLinkClass).join("")});var c=document.querySelector(e.tocSelector).querySelectorAll("."+e.listItemClass);u.call(c,function(t){t.className=t.className.split(h+e.activeListItemClass).join("")});var a=document.querySelector(e.tocSelector).querySelector("."+e.linkClass+".node-name--"+o.nodeName+'[href="#'+o.id+'"]');-1===a.className.indexOf(e.activeLinkClass)&&(a.className+=h+e.activeLinkClass);var p=a.parentNode;p&&-1===p.className.indexOf(e.activeListItemClass)&&(p.className+=h+e.activeListItemClass);var C=document.querySelector(e.tocSelector).querySelectorAll("."+e.listClass+"."+e.collapsibleClass);u.call(C,function(t){-1===t.className.indexOf(e.isCollapsedClass)&&(t.className+=h+e.isCollapsedClass)}),a.nextSibling&&-1!==a.nextSibling.className.indexOf(e.isCollapsedClass)&&(a.nextSibling.className=a.nextSibling.className.split(h+e.isCollapsedClass).join("")),r(a.parentNode.parentNode)}}function r(t){return-1!==t.className.indexOf(e.collapsibleClass)&&-1!==t.className.indexOf(e.isCollapsedClass)?(t.className=t.className.split(h+e.isCollapsedClass).join(""),r(t.parentNode.parentNode)):t}function c(t){var n=t.target||t.srcElement;"string"==typeof n.className&&-1!==n.className.indexOf(e.linkClass)&&(m=!1)}function a(){m=!0}var u=[].forEach,d=[].some,f=document.body,m=!0,h=" ";return{enableTocAnimation:a,disableTocAnimation:c,render:n,updateToc:s}}},function(e,t){e.exports=function(e){function t(e){return e[e.length-1]}function n(e){return+e.nodeName.split("H").join("")}function o(t){var o={id:t.id,children:[],nodeName:t.nodeName,headingLevel:n(t),textContent:t.textContent.trim()};return e.includeHtml&&(o.childNodes=t.childNodes),o}function l(l,i){for(var s=o(l),r=n(l),c=i,a=t(c),u=a?a.headingLevel:0,d=r-u;d>0;)a=t(c),a&&void 0!==a.children&&(c=a.children),d--;return r>=e.collapseDepth&&(s.isCollapsed=!0),c.push(s),c}function i(t,n){var o=n;e.ignoreSelector&&(o=n.split(",").map(function(t){return t.trim()+":not("+e.ignoreSelector+")"}));try{return document.querySelector(t).querySelectorAll(o)}catch(e){return console.warn("Element not found: "+t),null}}function s(e){return r.call(e,function(e,t){return l(o(t),e.nest),e},{nest:[]})}var r=[].reduce;return{nestHeadingsArray:s,selectHeadings:i}}},function(e,t){function n(e){function t(e){return"a"===e.tagName.toLowerCase()&&(e.hash.length>0||"#"===e.href.charAt(e.href.length-1))&&(n(e.href)===s||n(e.href)+"#"===s)}function n(e){return e.slice(0,e.lastIndexOf("#"))}function l(e){var t=document.getElementById(e.substring(1));t&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())}!function(){document.documentElement.style}();var i=e.duration,s=location.hash?n(location.href):location.href;!function(){function n(n){!t(n.target)||n.target.className.indexOf("no-smooth-scroll")>-1||"#"===n.target.href.charAt(n.target.href.length-2)&&"!"===n.target.href.charAt(n.target.href.length-1)||-1===n.target.className.indexOf(e.linkClass)||o(n.target.hash,{duration:i,callback:function(){l(n.target.hash)}})}document.body.addEventListener("click",n,!1)}()}function o(e,t){function n(e){s=e-i,window.scrollTo(0,c.easing(s,r,u,d)),s + + + + + + + Rest API + + + + + + + + + +
+
+

Spring Cloud Versions

+
+
+

Gets all the available Spring Cloud release trains.

+
+
+

cURL Request

+
+
+
$ curl 'http://spring-cloud-info.cfapps.io/springcloudversions' -i -X GET \
+    -H 'Accept: application/json'
+
+
+
+
+

HTTPie Request

+
+
+
$ http GET 'http://spring-cloud-info.cfapps.io/springcloudversions' \
+    'Accept:application/json'
+
+
+
+
+

HTTP Request

+
+
+
GET /springcloudversions HTTP/1.1
+Accept: application/json
+Host: spring-cloud-info.cfapps.io
+
+
+
+
+

Response

+
+
+
HTTP/1.1 200 OK
+Content-Length: 449
+Content-Type: application/json;charset=UTF-8
+
+["Greenwich.SR1","Greenwich.RELEASE","Greenwich.RC2","Greenwich.RC1","Greenwich.M3","Greenwich.M2","Greenwich.M1","Finchley.SR3","Finchley.SR2","Finchley.SR1","Finchley.RELEASE","Finchley.RC2","Finchley.RC1","Finchley.M9","Finchley.M8","Finchley.M7","Finchley.M6","Finchley.M5","Finchley.M3","Finchley.M2","Finchley.M1","Edgware.SR5","Edgware.SR4","Edgware.SR3","Edgware.SR2","Edgware.SR1","Edgware.RELEASE","Edgware.M1","Dalston.SR5","Dalston.SR4"]
+
+
+
+
+

Response Fields

+ + + + + + + + + + + + + + + + + + + + +
PathTypeDescription

[]

Array

An array versions

+
+
+
+
+

Spring Cloud Version Given Spring Boot + Version

+
+
+

Gets the Spring Cloud release train version given a Spring Boot version.

+
+
+

Path Parameters

+ + + + + + + + + + + + + + + + + + +
Table 1. /springcloudversion/springboot/{bootVersion}
ParameterDescription

bootVersion

The Spring Boot version

+
+
+

cURL Request

+
+
+
$ curl 'http://spring-cloud-info.cfapps.io/springcloudversion/springboot/2.1.1.RELEASE' -i -X GET \
+    -H 'Accept: application/json'
+
+
+
+
+

HTTPie Request

+
+
+
$ http GET 'http://spring-cloud-info.cfapps.io/springcloudversion/springboot/2.1.1.RELEASE' \
+    'Accept:application/json'
+
+
+
+
+

HTTP Request

+
+
+
GET /springcloudversion/springboot/2.1.1.RELEASE HTTP/1.1
+Accept: application/json
+Host: spring-cloud-info.cfapps.io
+
+
+
+
+

HTTP Response

+
+
+
HTTP/1.1 200 OK
+Content-Length: 31
+Content-Disposition: inline;filename=f.txt
+Content-Type: application/json;charset=UTF-8
+
+{"version":"Greenwich.RELEASE"}
+
+
+
+
+

Response Fields

+ + + + + + + + + + + + + + + + + + + + +
PathTypeDescription

version

String

Spring Cloud version

+
+
+
+
+

Spring Cloud Project Versions

+
+
+

Get the Spring Cloud project versions for a given Spring Cloud release train.

+
+
+

cURL Request

+
+
+
$ curl 'http://spring-cloud-info.cfapps.io/bomversions/Finchley.SR1' -i -X GET \
+    -H 'Accept: application/json'
+
+
+
+
+

HTTPie Request

+
+
+
$ http GET 'http://spring-cloud-info.cfapps.io/bomversions/Finchley.SR1' \
+    'Accept:application/json'
+
+
+
+
+

HTTP Request

+
+
+
GET /bomversions/Finchley.SR1 HTTP/1.1
+Accept: application/json
+Host: spring-cloud-info.cfapps.io
+
+
+
+
+

HTTP Response

+
+
+
HTTP/1.1 200 OK
+Content-Length: 904
+Content-Disposition: inline;filename=f.txt
+Content-Type: application/json;charset=UTF-8
+
+{"spring-cloud-cloudfoundry":"2.2.0.BUILD-SNAPSHOT","spring-cloud-openfeign":"2.2.0.BUILD-SNAPSHOT","spring-cloud-task":"2.0.0.RELEASE","spring-cloud-security":"2.2.0.BUILD-SNAPSHOT","spring-cloud-zookeeper":"2.2.0.BUILD-SNAPSHOT","spring-cloud-config":"2.2.0.BUILD-SNAPSHOT","spring-cloud-function":"2.1.0.BUILD-SNAPSHOT","spring-cloud-netflix":"2.2.0.BUILD-SNAPSHOT","spring-cloud-vault":"2.2.0.BUILD-SNAPSHOT","spring-cloud-stream":"Germantown.BUILD-SNAPSHOT","spring-cloud-gcp":"1.1.0.BUILD-SNAPSHOT","spring-cloud-sleuth":"2.2.0.BUILD-SNAPSHOT","spring-cloud-kubernetes":"1.1.0.BUILD-SNAPSHOT","spring-cloud-commons":"2.2.0.BUILD-SNAPSHOT","spring-cloud-aws":"2.2.0.BUILD-SNAPSHOT","spring-cloud-contract":"2.2.0.BUILD-SNAPSHOT","spring-cloud-bus":"2.2.0.BUILD-SNAPSHOT","spring-cloud-gateway":"2.2.0.BUILD-SNAPSHOT","spring-boot":"2.2.0.BUILD-SNAPSHOT","spring-cloud-consul":"2.2.0.BUILD-SNAPSHOT"}
+
+
+
+
+
+
+

Upcoming Spring Cloud Releases

+
+
+

Gets all the upcoming Spring Cloud releases.

+
+
+

cURL Request

+
+
+
$ curl 'http://spring-cloud-info.cfapps.io/milestones' -i -X GET \
+    -H 'Accept: application/json'
+
+
+
+
+

HTTPie Request

+
+
+
$ http GET 'http://spring-cloud-info.cfapps.io/milestones' \
+    'Accept:application/json'
+
+
+
+
+

HTTP Request

+
+
+
GET /milestones HTTP/1.1
+Accept: application/json
+Host: spring-cloud-info.cfapps.io
+
+
+
+
+

HTTP Response

+
+
+
HTTP/1.1 200 OK
+Content-Type: application/json;charset=UTF-8
+Content-Length: 57
+
+["Hoxton.RELEASE","Finchley.SR4","Hoxton.M1","Hoxton.M2"]
+
+
+
+
+
+
+

Get Spring Cloud Release Date

+
+
+

Gets the tentative date given an upcoming Spring Cloud release train name.

+
+
+

Path Parameters

+ + + + + + + + + + + + + + + + + + +
Table 2. /milestones/{release}/duedate
ParameterDescription

release

The Spring Cloud release train name

+
+
+

cURL Request

+
+
+
$ curl 'http://spring-cloud-info.cfapps.io/milestones/Hoxton.RELEASE/duedate' -i -X GET \
+    -H 'Accept: application/json'
+
+
+
+
+

HTTPie Request

+
+
+
$ http GET 'http://spring-cloud-info.cfapps.io/milestones/Hoxton.RELEASE/duedate' \
+    'Accept:application/json'
+
+
+
+
+

HTTP Request

+
+
+
GET /milestones/Hoxton.RELEASE/duedate HTTP/1.1
+Accept: application/json
+Host: spring-cloud-info.cfapps.io
+
+
+
+
+

HTTP Response

+
+
+
HTTP/1.1 200 OK
+Content-Type: application/json;charset=UTF-8
+Content-Length: 24
+
+{"dueDate":"2019-07-31"}
+
+
+
+
+

Response Fields

+ + + + + + + + + + + + + + + + + + + + +
PathTypeDescription

dueDate

String

Spring Cloud milestone due date

+
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/spring-cloud-info/src/test/java/org/springframework/cloud/info/InitializrSpringCloudInfoServiceTests.java b/spring-cloud-info/src/test/java/org/springframework/cloud/info/InitializrSpringCloudInfoServiceTests.java new file mode 100644 index 00000000..13ee4566 --- /dev/null +++ b/spring-cloud-info/src/test/java/org/springframework/cloud/info/InitializrSpringCloudInfoServiceTests.java @@ -0,0 +1,273 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.info; + +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.json.Json; +import javax.json.JsonBuilderFactory; +import javax.json.JsonObjectBuilder; +import javax.json.JsonValue; + +import com.jcabi.github.Coordinates; +import com.jcabi.github.Github; +import com.jcabi.github.Milestone; +import com.jcabi.github.Milestones; +import com.jcabi.github.Repo; +import com.jcabi.github.Repos; +import com.jcabi.http.Request; +import com.jcabi.http.RequestURI; +import com.jcabi.http.Response; +import com.jcabi.http.request.DefaultResponse; +import com.jcabi.http.response.JsonResponse; +import com.jcabi.immutable.Array; +import org.apache.commons.io.IOUtils; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import org.springframework.cloud.info.exceptions.SpringCloudVersionNotFoundException; +import org.springframework.core.io.ClassPathResource; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.fail; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import static org.springframework.cloud.info.SpringCloudInfoTestData.milestoneStrings; +import static org.springframework.cloud.info.SpringCloudRelease.SPRING_CLOUD_RELEASE_TAGS_PATH; + +/** + * @author Ryan Baxter + */ +class InitializrSpringCloudInfoServiceTests { + + @Test + void getSpringCloudVersionBomRangesMissingTest() { + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + when(rest.getForObject(anyString(), eq(Map.class))).thenReturn(new HashMap()); + InitializrSpringCloudInfoService service = new InitializrSpringCloudInfoService(rest, github, githubPomReader); + try { + service.getSpringCloudVersion("2.1.0"); + fail("Exception should have been thrown"); + } + catch (SpringCloudVersionNotFoundException e) { + assertThat(e.getCause().getMessage(), Matchers.startsWith("bom-ranges")); + } + } + + @Test + void getSpringCloudVersionSpringCloudMissingTest() { + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + Map> info = new HashMap<>(); + info.put("bom-ranges", new HashMap<>()); + when(rest.getForObject(anyString(), eq(Map.class))).thenReturn(info); + InitializrSpringCloudInfoService service = new InitializrSpringCloudInfoService(rest, github, githubPomReader); + try { + service.getSpringCloudVersion("2.1.0"); + fail("Exception should have been thrown"); + } + catch (SpringCloudVersionNotFoundException e) { + assertThat(e.getCause().getMessage(), Matchers.startsWith("spring-cloud")); + } + } + + @Test + void getSpringCloudReleaseVersionTest() throws Exception { + String bomVersion = "v2020.0.0-SNAPSHOT"; + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + when(githubPomReader + .readPomFromUrl(eq(String.format(SpringCloudRelease.SPRING_CLOUD_STARTER_PARENT_RAW, bomVersion)))) + .thenReturn(new MavenXpp3Reader().read(new FileReader( + new ClassPathResource("spring-cloud-starter-parent-pom.xml").getFile()))); + when(githubPomReader.readPomFromUrl( + eq(String.format(SpringCloudRelease.SPRING_CLOUD_RELEASE_DEPENDENCIES_RAW, bomVersion)))) + .thenReturn(new MavenXpp3Reader().read( + new FileReader(new ClassPathResource("spring-cloud-dependencies-pom.xml").getFile()))); + InitializrSpringCloudInfoService service = spy( + new InitializrSpringCloudInfoService(rest, github, githubPomReader)); + doReturn(Arrays.asList(bomVersion)).when(service) + .getSpringCloudVersions(); + Map releaseVersionsResult = service.getReleaseVersions(bomVersion); + assertThat(releaseVersionsResult, Matchers.equalTo(SpringCloudInfoTestData.releaseVersions)); + } + + @Test + void getSpringCloudReleaseVersionNotFoundTest() { + assertThatExceptionOfType(SpringCloudVersionNotFoundException.class).isThrownBy(() -> { + String bomVersion = "vFooBar.BUILD-SNAPSHOT"; + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + when(githubPomReader + .readPomFromUrl(eq(String.format(SpringCloudRelease.SPRING_CLOUD_STARTER_PARENT_RAW, bomVersion)))) + .thenReturn(new MavenXpp3Reader().read(new FileReader( + new ClassPathResource("spring-cloud-starter-parent-pom.xml").getFile()))); + when(githubPomReader.readPomFromUrl( + eq(String.format(SpringCloudRelease.SPRING_CLOUD_RELEASE_DEPENDENCIES_RAW, bomVersion)))) + .thenReturn(new MavenXpp3Reader().read( + new FileReader(new ClassPathResource("spring-cloud-dependencies-pom.xml").getFile()))); + InitializrSpringCloudInfoService service = spy( + new InitializrSpringCloudInfoService(rest, github, githubPomReader)); + doReturn(new ArrayList()).when(service).getSpringCloudVersions(); + service.getReleaseVersions(bomVersion); + }); + } + + @Test + void getSpringCloudVersionsTest() throws Exception { + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + Response response = mock(Response.class); + Request request = mock(Request.class); + RequestURI requestURI = mock(RequestURI.class); + JsonResponse jsonResponse = new JsonResponse(new DefaultResponse(request, 200, "", new Array<>(), + IOUtils.toByteArray(new ClassPathResource("spring-cloud-versions.json").getInputStream()))); + doReturn(request).when(requestURI).back(); + doReturn(requestURI).when(requestURI).path(eq(SPRING_CLOUD_RELEASE_TAGS_PATH)); + doReturn(requestURI).when(request).uri(); + doReturn(jsonResponse).when(response).as(eq(JsonResponse.class)); + doReturn(response).when(request).fetch(); + doReturn(request).when(github).entry(); + InitializrSpringCloudInfoService service = spy( + new InitializrSpringCloudInfoService(rest, github, githubPomReader)); + assertThat(service.getSpringCloudVersions(), Matchers.equalTo(SpringCloudInfoTestData.springCloudVersions + .stream().map(v -> v.replaceFirst("v", "")).collect(Collectors.toList()))); + } + + @Test + void getMilestoneDueDateTest() throws Exception { + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + Repos repos = mock(Repos.class); + Repo repo = mock(Repo.class); + Milestones milestones = mock(Milestones.class); + Iterable iterable = buildMilestonesIterable(); + doReturn(iterable).when(milestones).iterate(any(Map.class)); + doReturn(milestones).when(repo).milestones(); + doReturn(repo).when(repos).get(any(Coordinates.class)); + doReturn(repos).when(github).repos(); + InitializrSpringCloudInfoService service = spy( + new InitializrSpringCloudInfoService(rest, github, githubPomReader)); + assertThat(service.getMilestoneDueDate("Finchley.SR4"), + Matchers.equalTo(new SpringCloudInfoService.Milestone("No Due Date"))); + assertThat(service.getMilestoneDueDate("Hoxton.RELEASE"), + Matchers.equalTo(new SpringCloudInfoService.Milestone("2019-07-31"))); + } + + @Test + void getMilestonesTest() throws Exception { + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + Repos repos = mock(Repos.class); + Repo repo = mock(Repo.class); + Milestones milestones = mock(Milestones.class); + Iterable iterable = buildMilestonesIterable(); + doReturn(iterable).when(milestones).iterate(any(Map.class)); + doReturn(milestones).when(repo).milestones(); + doReturn(repo).when(repos).get(any(Coordinates.class)); + doReturn(repos).when(github).repos(); + InitializrSpringCloudInfoService service = spy( + new InitializrSpringCloudInfoService(rest, github, githubPomReader)); + assertThat(service.getMilestones(), Matchers.equalTo(milestoneStrings.keySet())); + + } + + private Iterable buildMilestonesIterable() throws IOException { + JsonBuilderFactory builderFactory = Json.createBuilderFactory(new HashMap<>()); + List milestonesList = new ArrayList<>(); + for (String m : milestoneStrings.keySet()) { + Milestone milestone = mock(Milestone.class); + String dueDate = milestoneStrings.get(m); + JsonObjectBuilder builder = builderFactory.createObjectBuilder().add("title", m); + if (dueDate == null) { + builder.add("due_on", JsonValue.NULL); + } + else { + builder.add("due_on", dueDate); + } + doReturn(builder.build()).when(milestone).json(); + milestonesList.add(milestone); + } + return (Iterable) () -> milestonesList.iterator(); + } + + @Test + void getSpringCloudVersionTest() throws Exception { + RestTemplate rest = mock(RestTemplate.class); + Github github = mock(Github.class); + GithubPomReader githubPomReader = mock(GithubPomReader.class); + Map springCloudVersions = generateSpringCloudData(); + Map> springCloud = new HashMap<>(); + springCloud.put("spring-cloud", springCloudVersions); + Map>> info = new HashMap<>(); + info.put("bom-ranges", springCloud); + when(rest.getForObject(anyString(), eq(Map.class))).thenReturn(info); + InitializrSpringCloudInfoService service = new InitializrSpringCloudInfoService(rest, github, githubPomReader); + String version = service.getSpringCloudVersion("2.1.0.RELEASE").getVersion(); + assertThat(version, Matchers.equalTo("Greenwich.SR1")); + version = service.getSpringCloudVersion("2.1.4.RELEASE").getVersion(); + assertThat(version, Matchers.equalTo("Greenwich.SR1")); + version = service.getSpringCloudVersion("2.1.5.RELEASE").getVersion(); + assertThat(version, Matchers.equalTo("Greenwich.BUILD-SNAPSHOT")); + version = service.getSpringCloudVersion("1.5.5.RELEASE").getVersion(); + assertThat(version, Matchers.equalTo("Edgware.SR5")); + version = service.getSpringCloudVersion("1.5.21.BUILD-SNAPSHOT").getVersion(); + assertThat(version, Matchers.equalTo("Edgware.BUILD-SNAPSHOT")); + } + + private Map generateSpringCloudData() { + Map data = new HashMap<>(); + data.put("Edgware.SR5", "Spring Boot >=1.5.0.RELEASE and <=1.5.20.RELEASE"); + data.put("Edgware.BUILD-SNAPSHOT", "Spring Boot >=1.5.21.BUILD-SNAPSHOT and <2.0.0.M1"); + data.put("Finchley.M2", "Spring Boot >=2.0.0.M3 and <2.0.0.M5"); + data.put("Finchley.M3", "Spring Boot >=2.0.0.M5 and <=2.0.0.M5"); + data.put("Finchley.M4", "Spring Boot >=2.0.0.M6 and <=2.0.0.M6"); + data.put("Finchley.RC1", "Spring Boot >=2.0.1.RELEASE and <2.0.2.RELEASE"); + data.put("Finchley.RC2", "Spring Boot >=2.0.2.RELEASE and <2.0.3.RELEASE"); + data.put("Finchley.SR3", "Spring Boot >=2.0.3.RELEASE and <2.0.999.BUILD-SNAPSHOT"); + data.put("Finchley.BUILD-SNAPSHO", "Spring Boot >=2.0.999.BUILD-SNAPSHOT and <2.1.0.M3"); + data.put("Greenwich.M1", "Spring Boot >=2.1.0.M3 and <2.1.0.RELEASE"); + data.put("Greenwich.SR1", "Spring Boot >=2.1.0.RELEASE and <2.1.5.BUILD-SNAPSHOT"); + data.put("Greenwich.BUILD-SNAPSHOT", "Spring Boot >=2.1.5.BUILD-SNAPSHOT"); + return data; + + } + +} diff --git a/spring-cloud-info/src/test/java/org/springframework/cloud/info/SpringCloudInfoRestControllerTests.java b/spring-cloud-info/src/test/java/org/springframework/cloud/info/SpringCloudInfoRestControllerTests.java new file mode 100644 index 00000000..a7c7aa8e --- /dev/null +++ b/spring-cloud-info/src/test/java/org/springframework/cloud/info/SpringCloudInfoRestControllerTests.java @@ -0,0 +1,126 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.info; + +import java.util.stream.Collectors; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.cloud.info.SpringCloudInfoService.SpringCloudVersion; +import org.springframework.http.MediaType; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.springframework.cloud.info.SpringCloudInfoTestData.springCloudVersions; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * @author Ryan Baxter + */ +@WebMvcTest(SpringCloudInfoRestController.class) +@ExtendWith(RestDocumentationExtension.class) +class SpringCloudInfoRestControllerTests { + + + @MockBean + SpringCloudInfoService springCloudInfoService; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext context; + + @BeforeEach + void setUp(RestDocumentationContextProvider restDocumentation) { + this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) + .apply(documentationConfiguration(restDocumentation).uris() + .withHost("spring-cloud-info.cfapps.io") + .withPort(80)) + .build(); + } + + @Test + void version() throws Exception { + doReturn(new SpringCloudVersion("Greenwich.RELEASE")).when(springCloudInfoService) + .getSpringCloudVersion(eq("2.1.1.RELEASE")); + this.mockMvc + .perform(get("/springcloudversion/springboot/{bootVersion}", "2.1.1.RELEASE") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("springcloudversion", + pathParameters(parameterWithName("bootVersion").description("The Spring Boot version")), + responseFields(fieldWithPath("version").description("Spring Cloud version")))); + } + + @Test + void versions() throws Exception { + doReturn(springCloudVersions.stream().map(v -> v.replaceFirst("v", "")) + .collect(Collectors.toList())) + .when(springCloudInfoService).getSpringCloudVersions(); + this.mockMvc.perform(get("/springcloudversions").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("springcloudversions", + responseFields(fieldWithPath("[]").description("An array versions")))); + } + + @Test + void bomVersions() throws Exception { + doReturn(SpringCloudInfoTestData.releaseVersions).when(springCloudInfoService) + .getReleaseVersions(eq("Finchley.SR1")); + this.mockMvc.perform(get("/bomversions/Finchley.SR1").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andDo(document("bomversions")); + } + + @Test + void milestones() throws Exception { + doReturn(SpringCloudInfoTestData.milestoneStrings.keySet()).when(springCloudInfoService) + .getMilestones(); + this.mockMvc.perform(get("/milestones").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("milestones")); + } + + @Test + void milestoneDueDate() throws Exception { + doReturn(new SpringCloudInfoService.Milestone("2019-07-31")).when(springCloudInfoService) + .getMilestoneDueDate(eq("Hoxton.RELEASE")); + this.mockMvc.perform(get("/milestones/{release}/duedate", "Hoxton.RELEASE").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("milestoneduedate", + pathParameters(parameterWithName("release").description("The Spring Cloud release train name")), + responseFields(fieldWithPath("dueDate").description("Spring Cloud milestone due date")))); + } + +} diff --git a/spring-cloud-info/src/test/java/org/springframework/cloud/info/SpringCloudInfoTestData.java b/spring-cloud-info/src/test/java/org/springframework/cloud/info/SpringCloudInfoTestData.java new file mode 100644 index 00000000..4e688500 --- /dev/null +++ b/spring-cloud-info/src/test/java/org/springframework/cloud/info/SpringCloudInfoTestData.java @@ -0,0 +1,106 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.info; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Ryan Baxter + */ +public final class SpringCloudInfoTestData { + + public static Map releaseVersions = new HashMap<>(); + + public static List springCloudVersions = new ArrayList<>(); + + public static Map milestoneStrings = new HashMap<>(); + + static { + releaseVersions.put("spring-boot", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-aws", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-bus", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-cloudfoundry", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-commons", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-config", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-consul", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-contract", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-function", "2.1.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-gateway", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-gcp", "1.1.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-kubernetes", "1.1.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-netflix", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-openfeign", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-security", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-sleuth", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-stream", "Germantown-SNAPSHOT"); + releaseVersions.put("spring-cloud-task", "2.0.0.RELEASE"); + releaseVersions.put("spring-cloud-vault", "2.2.0-SNAPSHOT"); + releaseVersions.put("spring-cloud-zookeeper", "2.2.0-SNAPSHOT"); + } + + static { + springCloudVersions.add("v2020.0.1"); + springCloudVersions.add("v2020.0.0"); + springCloudVersions.add("v2020.0.0-RC1"); + springCloudVersions.add("v2020.0.0-M1"); + springCloudVersions.add("vGreenwich.SR1"); + springCloudVersions.add("vGreenwich.RELEASE"); + springCloudVersions.add("vGreenwich.RC2"); + springCloudVersions.add("vGreenwich.RC1"); + springCloudVersions.add("vGreenwich.M3"); + springCloudVersions.add("vGreenwich.M2"); + springCloudVersions.add("vGreenwich.M1"); + springCloudVersions.add("vFinchley.SR3"); + springCloudVersions.add("vFinchley.SR2"); + springCloudVersions.add("vFinchley.SR1"); + springCloudVersions.add("vFinchley.RELEASE"); + springCloudVersions.add("vFinchley.RC2"); + springCloudVersions.add("vFinchley.RC1"); + springCloudVersions.add("vFinchley.M9"); + springCloudVersions.add("vFinchley.M8"); + springCloudVersions.add("vFinchley.M7"); + springCloudVersions.add("vFinchley.M6"); + springCloudVersions.add("vFinchley.M5"); + springCloudVersions.add("vFinchley.M3"); + springCloudVersions.add("vFinchley.M2"); + springCloudVersions.add("vFinchley.M1"); + springCloudVersions.add("vEdgware.SR5"); + springCloudVersions.add("vEdgware.SR4"); + springCloudVersions.add("vEdgware.SR3"); + springCloudVersions.add("vEdgware.SR2"); + springCloudVersions.add("vEdgware.SR1"); + springCloudVersions.add("vEdgware.RELEASE"); + springCloudVersions.add("vEdgware.M1"); + springCloudVersions.add("vDalston.SR5"); + springCloudVersions.add("vDalston.SR4"); + } + + static { + milestoneStrings.put("Hoxton.M1", "2019-05-23T07:00:00Z"); + milestoneStrings.put("Hoxton.M2", "2019-06-27T07:00:00Z"); + milestoneStrings.put("Hoxton.RELEASE", "2019-07-31T07:00:00Z"); + milestoneStrings.put("Finchley.SR4", null); + } + + private SpringCloudInfoTestData() { + throw new IllegalStateException("Can't instantiate utility class"); + } + +} diff --git a/spring-cloud-info/src/test/resources/spring-cloud-dependencies-pom.xml b/spring-cloud-info/src/test/resources/spring-cloud-dependencies-pom.xml new file mode 100644 index 00000000..e7b4286a --- /dev/null +++ b/spring-cloud-info/src/test/resources/spring-cloud-dependencies-pom.xml @@ -0,0 +1,225 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-dependencies-parent + 2.2.0.BUILD-SNAPSHOT + + + spring-cloud-dependencies + 2020.0.0-SNAPSHOT + spring-cloud-dependencies + Spring Cloud Dependencies + pom + + ${basedir}/../.. + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.1.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 1.1.0.BUILD-SNAPSHOT + 1.1.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + Germantown.BUILD-SNAPSHOT + 2.0.0.RELEASE + 2.2.0.BUILD-SNAPSHOT + 2.2.0.BUILD-SNAPSHOT + + + + + + org.springframework.cloud + spring-cloud-commons-dependencies + ${spring-cloud-commons.version} + pom + import + + + org.springframework.cloud + spring-cloud-netflix-dependencies + ${spring-cloud-netflix.version} + pom + import + + + org.springframework.cloud + spring-cloud-stream-dependencies + ${spring-cloud-stream.version} + pom + import + + + org.springframework.cloud + spring-cloud-task-dependencies + ${spring-cloud-task.version} + pom + import + + + org.springframework.cloud + spring-cloud-config-dependencies + ${spring-cloud-config.version} + pom + import + + + org.springframework.cloud + spring-cloud-function-dependencies + ${spring-cloud-function.version} + pom + import + + + org.springframework.cloud + spring-cloud-gateway-dependencies + ${spring-cloud-gateway.version} + pom + import + + + org.springframework.cloud + spring-cloud-consul-dependencies + ${spring-cloud-consul.version} + pom + import + + + org.springframework.cloud + spring-cloud-sleuth-dependencies + ${spring-cloud-sleuth.version} + pom + import + + + org.springframework.cloud + spring-cloud-vault-dependencies + ${spring-cloud-vault.version} + pom + import + + + org.springframework.cloud + spring-cloud-zookeeper-dependencies + ${spring-cloud-zookeeper.version} + pom + import + + + org.springframework.cloud + spring-cloud-security-dependencies + ${spring-cloud-security.version} + pom + import + + + org.springframework.cloud + spring-cloud-cloudfoundry-dependencies + ${spring-cloud-cloudfoundry.version} + pom + import + + + org.springframework.cloud + spring-cloud-bus-dependencies + ${spring-cloud-bus.version} + pom + import + + + org.springframework.cloud + spring-cloud-contract-dependencies + ${spring-cloud-contract.version} + pom + import + + + org.springframework.cloud + spring-cloud-aws-dependencies + ${spring-cloud-aws.version} + pom + import + + + org.springframework.cloud + spring-cloud-openfeign-dependencies + ${spring-cloud-openfeign.version} + pom + import + + + org.springframework.cloud + spring-cloud-kubernetes-dependencies + ${spring-cloud-kubernetes.version} + pom + import + + + org.springframework.cloud + spring-cloud-gcp-dependencies + ${spring-cloud-gcp.version} + pom + import + + + + + + spring + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + + + + + \ No newline at end of file diff --git a/spring-cloud-info/src/test/resources/spring-cloud-starter-parent-pom.xml b/spring-cloud-info/src/test/resources/spring-cloud-starter-parent-pom.xml new file mode 100644 index 00000000..c1a08588 --- /dev/null +++ b/spring-cloud-info/src/test/resources/spring-cloud-starter-parent-pom.xml @@ -0,0 +1,156 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.2.0.BUILD-SNAPSHOT + + org.springframework.cloud + spring-cloud-starter-parent + 2020.0.0-SNAPSHOT + spring-cloud-starter-parent + Spring Cloud Starter Parent + pom + https://projects.spring.io/spring-cloud + + Pivotal Software, Inc. + https://www.spring.io + + + ${basedir}/../.. + 2020.0.0-SNAPSHOT + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + https://github.com/spring-cloud + + spring-docs + + scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-cloud/docs/${project.artifactId}/${project.version} + + + + repo.spring.io + Spring Release Repository + https://repo.spring.io/libs-release-local + + + repo.spring.io + Spring Snapshot Repository + https://repo.spring.io/libs-snapshot-local + + + + + spring + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + https://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + false + + + + + + milestone + + + repo.spring.io + Spring Milestone Repository + https://repo.spring.io/libs-milestone-local + + + + + bintray + + + bintray + Jcenter Repository + https://api.bintray.com/maven/spring/jars/org.springframework.cloud:${bintray.package} + + + + + central + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus-staging + Nexus Release Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + \ No newline at end of file diff --git a/spring-cloud-info/src/test/resources/spring-cloud-versions.json b/spring-cloud-info/src/test/resources/spring-cloud-versions.json new file mode 100644 index 00000000..81516172 --- /dev/null +++ b/spring-cloud-info/src/test/resources/spring-cloud-versions.json @@ -0,0 +1,302 @@ +[ + { + "name": "vGreenwich.SR1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.SR1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.SR1", + "commit": { + "sha": "a9c903373dbfe70bf20410d242c026d700886678", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/a9c903373dbfe70bf20410d242c026d700886678" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5TUjE=" + }, + { + "name": "vGreenwich.RELEASE", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.RELEASE", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.RELEASE", + "commit": { + "sha": "b14ede22cb5de30c31cd50aa240cb321197ef8ef", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/b14ede22cb5de30c31cd50aa240cb321197ef8ef" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5SRUxFQVNF" + }, + { + "name": "vGreenwich.RC2", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.RC2", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.RC2", + "commit": { + "sha": "b5a008184bf4bbacab18c6ac3e6f762fe557dbec", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/b5a008184bf4bbacab18c6ac3e6f762fe557dbec" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5SQzI=" + }, + { + "name": "vGreenwich.RC1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.RC1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.RC1", + "commit": { + "sha": "c0f6f9acd93dc50051c880568c934a01c70a2092", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/c0f6f9acd93dc50051c880568c934a01c70a2092" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5SQzE=" + }, + { + "name": "vGreenwich.M3", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.M3", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.M3", + "commit": { + "sha": "96ff83431ace468e48b5dfa3215d05b25c83e009", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/96ff83431ace468e48b5dfa3215d05b25c83e009" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5NMw==" + }, + { + "name": "vGreenwich.M2", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.M2", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.M2", + "commit": { + "sha": "28ba483beb02b874013eb29a3cdeb09c1394998a", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/28ba483beb02b874013eb29a3cdeb09c1394998a" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5NMg==" + }, + { + "name": "vGreenwich.M1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vGreenwich.M1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vGreenwich.M1", + "commit": { + "sha": "864aad4350d7c07a3b975d0522cb9f0a3442eec0", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/864aad4350d7c07a3b975d0522cb9f0a3442eec0" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkdyZWVud2ljaC5NMQ==" + }, + { + "name": "vFinchley.SR3", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.SR3", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.SR3", + "commit": { + "sha": "ce81fa120aef0d00a8c95664b373377eca8de3d7", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/ce81fa120aef0d00a8c95664b373377eca8de3d7" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5LlNSMw==" + }, + { + "name": "vFinchley.SR2", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.SR2", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.SR2", + "commit": { + "sha": "34ea6d4e2e751159589113d25f4a6510e4ed374b", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/34ea6d4e2e751159589113d25f4a6510e4ed374b" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5LlNSMg==" + }, + { + "name": "vFinchley.SR1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.SR1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.SR1", + "commit": { + "sha": "b3e3ab5f0e3badeaf4fab0d432c8881327c00a16", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/b3e3ab5f0e3badeaf4fab0d432c8881327c00a16" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5LlNSMQ==" + }, + { + "name": "vFinchley.RELEASE", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.RELEASE", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.RELEASE", + "commit": { + "sha": "f7c64759e431b583d5da11422b7b67a2a323c5c8", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/f7c64759e431b583d5da11422b7b67a2a323c5c8" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5LlJFTEVBU0U=" + }, + { + "name": "vFinchley.RC2", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.RC2", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.RC2", + "commit": { + "sha": "04dbea43b6f9b42b8b4b68a04b698df56b99b438", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/04dbea43b6f9b42b8b4b68a04b698df56b99b438" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5LlJDMg==" + }, + { + "name": "vFinchley.RC1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.RC1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.RC1", + "commit": { + "sha": "54ea18c4aee39654dbc4ffdf1808fb79654ec035", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/54ea18c4aee39654dbc4ffdf1808fb79654ec035" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5LlJDMQ==" + }, + { + "name": "vFinchley.M9", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M9", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M9", + "commit": { + "sha": "2ed336bd8719ef2096390d4cb905c1b779046f0c", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/2ed336bd8719ef2096390d4cb905c1b779046f0c" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk05" + }, + { + "name": "vFinchley.M8", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M8", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M8", + "commit": { + "sha": "eecc0e960b8b7e2bfd4c67138d4b88df43f9b7b6", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/eecc0e960b8b7e2bfd4c67138d4b88df43f9b7b6" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk04" + }, + { + "name": "vFinchley.M7", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M7", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M7", + "commit": { + "sha": "2377cfd5386bc985d6d13bf3d9605249d66538e4", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/2377cfd5386bc985d6d13bf3d9605249d66538e4" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk03" + }, + { + "name": "vFinchley.M6", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M6", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M6", + "commit": { + "sha": "3fbd9d7086627a1453c61e92e79259a2f3c3c8c1", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/3fbd9d7086627a1453c61e92e79259a2f3c3c8c1" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk02" + }, + { + "name": "vFinchley.M5", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M5", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M5", + "commit": { + "sha": "2be145fa2dc7a8afe5f379920300b029b439ffeb", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/2be145fa2dc7a8afe5f379920300b029b439ffeb" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk01" + }, + { + "name": "vFinchley.M3", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M3", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M3", + "commit": { + "sha": "e7362196ec5a5d9761a2668e4ef91a3ea3345a61", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/e7362196ec5a5d9761a2668e4ef91a3ea3345a61" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk0z" + }, + { + "name": "vFinchley.M2", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M2", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M2", + "commit": { + "sha": "fbac1e822c91cf2acfc542a01d2aae758e9143e8", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/fbac1e822c91cf2acfc542a01d2aae758e9143e8" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk0y" + }, + { + "name": "vFinchley.M1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vFinchley.M1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vFinchley.M1", + "commit": { + "sha": "af82b2d3ba2213dedd431f69e733923fbd81d11e", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/af82b2d3ba2213dedd431f69e733923fbd81d11e" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkZpbmNobGV5Lk0x" + }, + { + "name": "vEdgware.SR5", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.SR5", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.SR5", + "commit": { + "sha": "e913188e3ad1f2eaff7789d2738c5c27a8d81393", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/e913188e3ad1f2eaff7789d2738c5c27a8d81393" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuU1I1" + }, + { + "name": "vEdgware.SR4", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.SR4", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.SR4", + "commit": { + "sha": "8a05a2f6b796777671c88b83526b8af79a1f59e1", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/8a05a2f6b796777671c88b83526b8af79a1f59e1" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuU1I0" + }, + { + "name": "vEdgware.SR3", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.SR3", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.SR3", + "commit": { + "sha": "c20a51ae0f0066ea221597b5e86b5b55dca1a2af", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/c20a51ae0f0066ea221597b5e86b5b55dca1a2af" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuU1Iz" + }, + { + "name": "vEdgware.SR2", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.SR2", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.SR2", + "commit": { + "sha": "759413db879f79656ed9350e04b26dbc7a133992", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/759413db879f79656ed9350e04b26dbc7a133992" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuU1Iy" + }, + { + "name": "vEdgware.SR1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.SR1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.SR1", + "commit": { + "sha": "35e48e2fd1740ff7ae821fc3e61337c215737bb8", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/35e48e2fd1740ff7ae821fc3e61337c215737bb8" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuU1Ix" + }, + { + "name": "vEdgware.RELEASE", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.RELEASE", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.RELEASE", + "commit": { + "sha": "e39b986ec68d0a7b8b4a56281adfb9de096def53", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/e39b986ec68d0a7b8b4a56281adfb9de096def53" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuUkVMRUFTRQ==" + }, + { + "name": "vEdgware.M1", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vEdgware.M1", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vEdgware.M1", + "commit": { + "sha": "5fce865896095137266c788a84ba9843f6781882", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/5fce865896095137266c788a84ba9843f6781882" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkVkZ3dhcmUuTTE=" + }, + { + "name": "vDalston.SR5", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vDalston.SR5", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vDalston.SR5", + "commit": { + "sha": "d989c6b96590a8bafef5c0352908fcd4673836db", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/d989c6b96590a8bafef5c0352908fcd4673836db" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkRhbHN0b24uU1I1" + }, + { + "name": "vDalston.SR4", + "zipball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/zipball/vDalston.SR4", + "tarball_url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/tarball/vDalston.SR4", + "commit": { + "sha": "28c14699695a76843a6d1c347b1f21055d83ca62", + "url": "https://api.github.com/repos/spring-cloud/spring-cloud-release/commits/28c14699695a76843a6d1c347b1f21055d83ca62" + }, + "node_id": "MDM6UmVmMjI0ODI2NjQ6dkRhbHN0b24uU1I0" + } +] \ No newline at end of file