diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 8904bf68..00000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: - - main - pull_request: - branches: - - main - schedule: - - cron: '30 23 * * 5' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - permissions: - security-events: write - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: java - - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index dc92e315..00000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Java CI (Maven) - -on: - pull_request: - push: - branches: - - main - release: - types: - - created - -jobs: - build: - name: Build - - runs-on: ubuntu-latest - - strategy: - matrix: - java-version: ['11', '17'] - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK ${{ matrix.java-version }} - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java-version }} - - name: Build - run: mvn install -DskipTests=true -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true -B -V - env: - CI: true - - test: - name: Tests - - runs-on: ubuntu-latest - - strategy: - matrix: - java-version: ['11', '17'] - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK ${{ matrix.java-version }} - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java-version }} - - name: Test - run: mvn test -B - env: - CI: true - - checkstyle: - name: Checkstyle Audit - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Checkstyle - run: mvn verify -DskipTests=true -Dmaven.javadoc.skip=true -B - env: - CI: true - - javadoc: - name: JavaDoc Generation - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Generate JavaDoc - run: mvn verify -DskipTests=true -Dcheckstyle.skip=true -B - env: - CI: true diff --git a/.github/workflows/slate-docs.yml b/.github/workflows/slate-docs.yml deleted file mode 100644 index ee1ff29e..00000000 --- a/.github/workflows/slate-docs.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Slate Docs - -on: - pull_request: - push: - branches: - - main - release: - types: - - created - -jobs: - build: - runs-on: ubuntu-latest - env: - ruby-version: 3.3 - - steps: - - uses: actions/checkout@v3 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.ruby-version }} - - - uses: actions/cache@v4 - with: - path: vendor/bundle - key: gems-${{ runner.os }}-${{ env.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }} - - - run: bundle config set deployment 'true' - working-directory: ./slate-docs - - run: bundle install - working-directory: ./slate-docs - - - run: bundle exec middleman build - working-directory: ./slate-docs - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - if: ${{ github.event_name == 'release' }} - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./slate-docs/build diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2127990d..00000000 --- a/.gitignore +++ /dev/null @@ -1,48 +0,0 @@ -###################### -# Eclipse -###################### -.project -.metadata -bin -tmp -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings -.loadpath - -###################### -# Intellij -###################### -.idea -*.iml -*.iws -*.ipr -*.ids -*.orig - -###################### -# NetBeans -###################### -nb-configuration.xml -nbactions.xml - -###################### -# Maven -###################### -target -release.properties -pom.xml.releaseBackup - -###################### -# Slate Docs -###################### -slate-docs/build - -###################### -# OS -###################### -.DS_Store diff --git a/jsonschema-maven-plugin/src/test/resources/dummy-classpathes/both/.gitkeep b/.nojekyll similarity index 100% rename from jsonschema-maven-plugin/src/test/resources/dummy-classpathes/both/.gitkeep rename to .nojekyll diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 1f443b8d..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,938 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] -### `jsonschema-module-jackson` -#### Fixed -- support `@JacksonAnnotationsInside` annotated combo annotations also when looking for `@JsonPropertyDescription` - -## [4.38.0] - 2025-03-24 -### `jsonschema-generator` -#### Changed -- avoid duplicate entries in `required` array when performing final clean-ups - -### `jsonschema-module-swagger2` -#### Fixed -- respect `Option.NULLABLE_FIELDS_BY_DEFAULT`/`Option.NULLABLE_METHOD_RETURN_VALUES_BY_DEFAULT` for fields/methods without `@Schema` annotation - -## [4.37.0] - 2024-11-11 -### `jsonschema-generator` -#### Added -- new `Option.NULLABLE_ALWAYS_AS_ANYOF` that avoids the `"null"` type being included with other type values, e.g. `"type": ["object", "null"]` - -#### Changed -- apply property name overrides before triggering the ignore check (i.e., provide both the declared and overridden property names if there is one) -- update various (runtime/test/build-time) dependencies - -#### Fixed -- avoid exception when trying to collect supported enum values from raw `Enum` type (i.e., missing type parameter) -- avoid exception when trying to find type with annotation when given type is `null` - -### `jsonschema-module-jackson` -#### Added -- support `@JacksonAnnotationsInside` annotated combo annotations - -#### Fixed -- avoid exception in subtype resolution, when targeting void method -- check for ignored properties excluded fields when a property name override makes it conflict with a non-conventional getter method - -### `jsonschema-maven-plugin` -#### Added -- support `` flag to exclude abstract types (not interfaces) -- support `` flag to exclude interface types - -## [4.36.0] - 2024-07-20 -### `jsonschema-generator` -#### Added -- new `Option.ACCEPT_SINGLE_VALUE_AS_ARRAY` to support Jackson `DeserializationFeature` of the same name, i.e., when an array type is declared, an instance of a single item should also be accepted by the schema - -#### Changed -- consider `Boolean` values as valid in `const`/`enum` (i.e., no longer ignore them) - -### `jsonschema-module-jakarta-validation` -#### Added -- populate `const`/`enum` based on `@AssertTrue`/`@AssertFalse` - -## [4.35.0] - 2024-03-29 -### `jsonschema-generator` -#### Added -- check for custom definitions for `void` methods (this may result in exceptions inside custom configuration if a `null` return type is not considered) - -#### Changed -- if present, apply custom definition for `void` methods - -## [4.34.0] - 2024-03-14 -### `jsonschema-generator` -#### Added -- new `Option.DUPLICATE_MEMBER_ATTRIBUTE_CLEANUP_AT_THE_END` discard duplicate elements from member sub-schemas - -#### Changed -- new `Option.DUPLICATE_MEMBER_ATTRIBUTE_CLEANUP_AT_THE_END` by default included in standard `OptionPreset`s - -### `jsonschema-module-jackson` -#### Fixed -- `@JsonUnwrapped` annotation on inherited properties resulted in those properties being ignored instead of being unwrapped - -## [4.33.1] - 2023-12-19 -### `jsonschema-module-jackson` -#### Fixed -- Respect `@JsonPropertyOrder` also for properties derived from non-getter methods - -## [4.33.0] - 2023-11-23 -### `jsonschema-generator` -#### Added -- new `Option.STANDARD_FORMATS` includes standard `"format"` values to some types considered by `Option.ADDITIONAL_FIXED_TYPES` -- new `Option.INLINE_NULLABLE_SCHEMAS` avoids `"-nullable"` entries in the `"definitions"`/`"$defs"` - -#### Changed -- include new `Option.STANDARD_FORMATS` in `OptionPreset.PLAIN_JSON` by default -- extended parameters for creation of `FieldScope`/`MethodScope` through the `TypeContext` to include type for which a schema is being generated - -#### Fixed -- when using `Option.FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS` on a method where the second character of the derived field name is in uppercase, don't capitalise the first character - -## [4.32.0] - 2023-10-27 -### `jsonschema-generator` -#### Added -- offer `SchemaGeneratorConfigBuilder.withObjectMapper()`; mainly for use in custom modules in combination with the Maven plugin, where the constructor parameter cannot be used instead - -#### Changed -- consider JavaBeans API specification in getter naming convention for field names with the second character being uppercase (e.g., a field `xIndex` has the getter `getxIndex()` according to the specification) -- allow for field names starting with `is` to have a getter of the same name (e.g., a field `isBool` may have the getter `isBool()`) -- the default `ObjectMapper` instance now includes the enabled `SerializationFeature.INDENT_OUTPUT` - -### `jsonschema-module-jackson` -#### Added -- elevate nested properties to the parent type where members are annotated with `@JsonUnwrapped` - -### `jsonschema-module-swagger-2` -***NOTE: `io.swagger.core.v3:swagger-annotations` minimum version is now `2.2.5`!*** -#### Added -- consider `@Schema(additionalProperties = ...)` attribute (only values `TRUE` and `FALSE`), when it is annotated on a type (not on a member) -- consider `@Schema(requiredMode = REQUIRED)` in addition to deprecated `@Schema(required = true)` - -#### Fixed -- avoid rounding error when taking over the value from `@Schema(multipleOf)` - -### `jsonschema-maven-plugin` -### Added -- support custom configuration `Module` being loaded from test classpath elements - -### Changed -- a generated schema is now serialized through the configuration's `ObjectMapper` instance (e.g., granting control over pretty printing or even generating YAML instead of JSON files) - -## [4.31.1] - 2023-04-28 -### `jsonschema-generator` -#### Fixed -- avoid error being thrown in `allOf` clean-up for invalid payload - -## [4.31.0] - 2023-04-22 -### `jsonschema-generator` -#### Added -- extend `TypeContext` creation to support configuration of differing annotation inheritance by annotation type - -### `jsonschema-module-jakarta-validation` -#### Fixed -- consider inheritance of validation constraint annotations -- when limiting scope to validation groups, also consider a specified group's supertypes - -### `jsonschema-module-javax-validation` -#### Fixed -- consider inheritance of validation constraint annotations -- when limiting scope to validation groups, also consider a specified group's supertypes - -## [4.30.0] - 2023-04-16 -### `jsonschema-generator` -#### Added -- introduce configuration option for `dependentRequired` keyword -- introduce new `Option.STRICT_TYPE_INFO` for implying the `type` of sub-schemas based on their contained attributes (note: implied "type" array always contains "null") -- extend convenience methods for annotation lookup, to consider meta annotations (annotations on annotations) - -#### Changed -- enable `allOf` clean-up when any of the following keywords are contained: `dependentRequired`/`dependentSchemas`/`prefixItems`/`unevaluatedItems`/`unevaluatedProperties` -- extend consideration of sub-schemas for `allOf` clean-up to more recognized keywords - -### `jsonschema-module-jackson` -#### Added -- introduce new `JacksonOption.INLINE_TRANSFORMED_SUBTYPES` in order to avoid definitions with `-1`/`-2` suffixes being generated in case of subtypes involving transformation (e.g., additional property, wrapping array, wrapping object) - To be used with care, as a recursive reference can cause a `StackOverflowError`. In some scenarios, such an error can be avoided by also enabling the `Option.DEFINITIONS_FOR_MEMBER_SUPERTYPES`. - -#### Fixed -- use `prefixItems` instead of `items` keyword (from Draft 2019-09 onward) for tuples in `WRAPPING_ARRAY` subtype definitions - -### `jsonschema-module-jakarta-validation` -#### Added -- support meta annotations (validation annotations on other annotations marked as `@Constraint`) - -### `jsonschema-module-javax-validation` -#### Added -- support meta annotations (validation annotations on other annotations marked as `@Constraint`) - -### `jsonschema-examples` -#### Added -- new collection of examples (and implicit integration test) holding various examples (e.g., ones created in response to issues/discussions on GitHub) - -## [4.29.0] - 2023-03-13 -### `jsonschema-generator` -#### Added -- include basic Java module descriptor (also for standard modules and maven plugin) -- add possibility to reset various types of configuration aspects after a schema was generated, to enable re-using a generator instance even if it is stateful (i.e., behaves differently on subsequent invocations) - -#### Changed -- treat `java.time.Period` as `{ "type": "string" }` when `Option.ADDITIONAL_FIXED_TYPES` is enabled -- treat `java.time.LocalTime` and `java.time.OffsetTime` as `{ "format": "time" }` when `Option.ADDITIONAL_FIXED_TYPES` is enabled (instead of "date-time") -- update jackson dependency from version `2.13.4.20221013` to `2.14.2` and replace usage of now deprecated methods - -### `jsonschema-module-swagger-2` -#### Added -- consider `@Schema(ref = "...")` attribute, when it is annotated on a type (and not just a member) except for the main type being targeted - -### `jsonschema-maven-plugin` -#### Fixed -- regression: filtering of considered classes for schema generation stopped working (after migration to `classgraph` in 4.28.0) - -## [4.28.0] - 2022-10-31 -### `jsonschema-generator` -#### Added -- enable look-up of annotations on a member's type parameter (e.g., a `Map`'s value type) -- enable providing full custom schema definition to be included in `additionalProperties` or `patternProperties` -- new function `TypeContext.getTypeWithAnnotation()` for finding also super type of interface with certain type annotation -- new function `TypeContext.getTypeAnnotationConsideringHierarchy()` for searching type annotations also on super types and interfaces - -#### Changed -- consider annotations on `Map` value types when using `Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES` -- enhanced schema clean-up at the end: consolidating `allOf` with distinct `properties` (mostly relevant in jackson subtype resolution) -- enhanced schema clean-up at the end: consolidating `allOf` even with some keywords being present with differing values -- bump `slf4j-api` dependency version from `1.7.35` to `2.0.3` -- bump `jackson-core` dependency version from `2.13.2` to `2.13.4` -- bump `jackson-databind` dependency version from `2.13.2.2` to `2.13.4.2` - -#### Fixed -- custom property definition containing only a definition reference/placeholder is being ignored - -### `jsonschema-module-jackson` -#### Added -- new `JacksonOption.JSONIDENTITY_REFERENCE_ALWAYS_AS_ID` to respect `@JsonIdentityReference(alwaysAsId=true)` annotations (with `@JsonIdentityInfo`) - -### `jsonschema-module-jakarta-validation` -#### Added -- set `minProperties`/`maxProperties` for `Map` types with `@NotEmpty` or `@Size` annotation - -#### Changed -- bump `jakarta-validation-api` compile dependency version from `3.0.0` to `3.0.2` - -### `jsonschema-module-swagger-1.5` -#### Changed -- bump `swagger-annotations` compile dependency version from `1.5.22` to `1.6.7` - -### `jsonschema-module-swagger-2` -#### Changed -- bump `swagger-annotations` compile dependency version from `2.1.2` to `2.2.3` -- bump `swagger-core` compile dependency version from `2.1.2` to `2.2.3` - -### `jsonschema-maven-plugin` -#### Changed -- use `classgraph` dependency for classpath scanning determining entry points for schema generation - -#### Removed -- allow non-public classes as entry points for schema generation -- `reflections` dependency - -## [4.27.0] - 2022-09-29 -### `jsonschema-generator` -#### Added -- new `Option.DEFINITIONS_FOR_MEMBER_SUPERTYPES` to disable the transparent member subtype resolution, i.e., enable inclusion of a supertype schema -- new `DefinitionType.ALWAYS_REF` for custom definitions, to produce centralised definition even if just referenced once - -#### Fixed -- under some circumstances, even after the general schema clean-up procedure there were unnecessary `allOf` wrappers containing just a single entry - -#### Changed -- enable moving subtype schema into `$defs` and thereby reduce number of unnecessary `anyOf` wrappers - -### `jsonschema-module-jackson` -#### Added -- new `JacksonOption.ALWAYS_REF_SUBTYPES`, to produce centralised definition for each resolved subtype (wrapper) even if just referenced once - -### `jsonschema-maven-plugin` -#### Added -- support `` parameter in order to also consider compile dependencies for the schema generation (and/or ignoring runtime dependencies) -- support `` parameter in order to allow selecting classes to generate a schema for by the presence of certain type annotations - -## [4.26.0] - 2022-08-22 -### `jsonschema-module-jackson` -#### Changed -- support `@JsonTypeInfo.defaultImpl` in combination with `As.PROPERTY`, to no longer require the type property for the specified default subtype - -### `jsonschema-module-swagger-2` -#### Added -- support `@Schema.anyOf` and `@Schema.oneOf` on fields/methods - -### `jsonschema-maven-plugin` -#### Added -- support `false` parameter, in order to continue build even if no class matches the defined pattern(s) - -## [4.25.0] - 2022-06-24 -### `jsonschema-generator` -#### Added -- new `Option.FLATTENED_SUPPLIERS` to unwrap the supplied type; `Supplier` would thus be a type `T` - -#### Fixed -- when resolving subtypes with a single other type, under some circumstances the type definition gets lost -- set default `ObjectMapper` node factory to `JsonNodeFactory.withExactBigDecimals(true)` to avoid scientific notation for numbers - -#### Changed -- new `Option.FLATTENED_SUPPLIERS` is enabled by default in the `OptionPreset.PLAIN_JSON` -- existing `Option.FLATTENED_OPTIONALS` now also considers `Optional` container items (e.g., `List>`). - -## [4.24.3] - 2022-05-03 -### `jsonschema-generator` -#### Fixed -- ensure thread-safety when `Option.INLINE_ALL_SCHEMAS` is enabled - -### `jsonschema-module-jackson` -#### Fixed -- `@JsonPropertyOrder` is only considered on the targeted type, i.e., no attempt is made to respect a super type's property order -- ensure thread-safety when loading bean descriptions - -## [4.24.2] - 2022-04-04 -### `jsonschema-generator-bom` -#### Fixed -- Actually publish BOM during release - -### `jsonschema-generator-parent` -#### Changed -- Use BOM as parent and introduce separate reactor build definition - -## [4.24.1] - 2022-04-01 -### `jsonschema-generator` -#### Dependency Update -- Bump `jackson-databind` dependency to `2.13.2.2` to avoid security vulnerability -- Bump other `jackson` dependencies to `2.13.2` - -## [4.24.0] - 2022-04-01 -### `jsonschema-generator` -#### Fixed -- When looking-up a matching field or getter, only consider the declared property names and not any overrides - -### `jsonschema-module-jackson` -#### Added -- Support for subtype resolution on properties with `JsonTypeInfo.Id.NONE` override avoiding the default wrapping/modification - -#### Fixed -- Correctly consider `@JsonIgnoreProperties` targeting fields in super type - -## [4.23.0] - 2022-03-13 -### `jsonschema-generator-bom` -#### Added -- Introduce BOM (Bill of Materials) artifact, as option for importing Generator + Modules with matching versions - -### `jsonschema-maven-plugin` -#### Added -- Declare thread-safety, to avoid warnings at runtime - -### `jsonschema-module-jackson` -#### Fixed -- Subtype resolution utilising `JsonTypeInfo.Id.NAME` now considers `@JsonSubTypes.value[].name` instead of relying on `@JsonTypeName` being present - -#### Changed -- Subtype resolution utilising `JsonTypeInfo.As.PROPERTY`/`JsonTypeInfo.As.EXISTING_PROPERTY` now marks discriminator property as `"required"` -- Subtype resolution utilising `JsonTypeInfo.As.WRAPPER_OBJECT` now marks discriminator value as `"required"` in wrapper object - -## [4.22.0] - 2022-01-10 -### `jsonschema-generator` -#### Added -- Introduce support for `SchemaVersion.DRAFT_2020_12` - -#### Dependency Update -- Replace `log4j` test dependency with `logback` (still only test dependency) - -### `jsonschema-maven-plugin` -#### Fixed -- Enable usage under JDK11 (by adjusting usage of `reflections`, in order to allow finding classes in dependencies/jar) - -#### Dependency Update -- Update `reflections` runtime dependency from 0.9.12 to 0.10.2 - -## [4.21.0] - 2021-12-03 -### `jsonschema-generator` -#### Fixed -- prevent mixing of `type: null` with `const`/`enum` in order to avoid validation error when `const`/`enum` does not include `null` - -#### Changed -- default `ObjectMapper` when none is given in `SchemaGeneratorConfigBuilder` constructor now enables `JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS` - -### `jsonschema-module-jackson` -#### Added -- Consider `@JsonProperty.value` override for methods -- Look-up `"description"` for methods (if included) based on `@JsonPropertyDescription` -- Consider `@JsonProperty(access = Access.READ_ONLY)` when determining whether a field/method should be marked as `readOnly` -- Consider `@JsonProperty(access = Access.WRITE_ONLY)` when determining whether a field/method should be marked as `writeOnly` -- Introduce `JacksonOption.INCLUDE_ONLY_JSONPROPERTY_ANNOTATED_METHODS` to enable easy inclusion of annotated non-getter methods (typically in combination with the general `Option.FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS` and `Option.NONSTATIC_NONVOID_NONGETTER_METHODS`) - -#### Changed -- Ignore getter methods when their associated field is being ignored (according to various Jackson annotations) -- Ignore methods when they or their associated field are marked as `@JsonBackReference` - -## [4.20.0] - 2021-09-04 -### `jsonschema-generator` -#### Added -- Support for `null` values in collections/containers/arrays -- New opt-in `Option.NULLABLE_ARRAY_ITEMS_ALLOWED` for enabling the respective "NullableCheck" to be considered for items in a field's array value or a method's array return value - -### `jsonschema-module-swagger-2` -#### Added -- Consider `@ArraySchema(schema = @Schema(nullable = true))` if the new `Option.NULLABLE_ARRAY_ITEMS_ALLOWED` is enabled - -## [4.19.0] - 2021-09-02 -### `jsonschema-generator` -#### Added -- Support `readOnly` and `writeOnly` keywords - -### `jsonschema-module-jackson` -#### Changed -- subtype resolution now also respects `@JsonTypeInfo` annotation on common interface (and not just common super class) - -### `jsonschema-module-swagger-2` -#### Added -- Mark a subschema as `readOnly` or `writeOnly` based on a field or method's `@Schema.accessMode` - -## [4.18.0] - 2021-03-21 -### `jsonschema-generator` -#### Changed -- Increase of Jackson dependency version to 2.12.1 -- Include `java.net.URI` in handling of `Option.ADDITIONAL_FIXED_TYPES`. - -### `jsonschema-module-jackson` -#### Added -- New `JacksonOption.RESPECT_JSONPROPERTY_REQUIRED` to set a field as "required" based on `@JsonProperty` annotations - -#### Changed -- Replace deprecated Jackson API usage, resulting in MINIMUM Jackson version 2.12.0 - -## [4.17.0] - 2020-12-24 -### `jsonschema-module-jakarta-validation` -#### Added -- Initial implementation (initial features are equivalent to `jsonschema-module-javax-validation`) - -### `jsonschema-maven-plugin` -#### Added -- Support for new `jakarta.validation` module - -## [4.16.0] - 2020-09-25 -### `jsonschema-generator` -#### Added -- New `Option.ENUM_KEYWORD_FOR_SINGLE_VALUES` to produce `"enum": ["A"]` instead of `"const": "A"` if there is only one allowed value. - -## [4.15.1] - 2020-09-15 -### `jsonschema-generator` -#### Fixed -- Missing parentheses on void argument-free methods that don't start with "get" or "is" when enabling `Option.FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS` - -## [4.15.0] - 2020-09-15 -### `jsonschema-generator` -#### Added -- New `Option.EXTRA_OPEN_API_FORMAT_VALUES` to support automatic inclusion of `"format"` values for certain simple/fixed types - -### `jsonschema-module-javax-validation` -#### Added -- Support picking up annotations on a (top-level) generic `Optional` parameter (e.g. `Optional<@Size(min=2) String>`) - -## [4.14.0] - 2020-08-02 -### `jsonschema-generator` -#### Added -- Entries in `SchemaKeyword` enum for `"not"`, `"minProperties"`, `"maxProperties"` (without further handling) - -### `jsonschema-module-swagger-2` -#### Changed -- Make use of new `SchemaKeyword` enum entries instead of hard-coded strings (no change in behaviour) - -### `jsonschema-maven-plugin` -#### Added -- Support for including classes via glob patterns in `` and `` (in addition to absolute paths) -- Support for excluding classes via absolute paths or glob patterns in new `` - -#### Fixed -- Explicitly include dependencies of supported generator modules that they expect to be provided -- Avoid generating the same schema multiple times if there are overlaps between entries in `` and/or `` - -## [4.13.0] - 2020-06-27 -### `jsonschema-generator` -#### Added -- Possibility to configure `SchemaDefinitionNamingStrategy` via `configBuilder.forTypesInGeneral().withDefinitionNamingStrategy()` -- Explicit `DefaultSchemaDefinitionNamingStrategy` that is being applied if no other `SchemaDefinitionNamingStrategy` is being configured -- New `Option.FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS` to allow deriving fields from getter methods - -#### Changed -- Determine names/keys of subschemas in `definitions`/`$defs` through configurable `SchemaDefinitionNamingStrategy` -- Default property sort order to consider property name when differentiating fields and methods (now that methods may have field-like names) - -#### Fixed -- For multiple definitions for the same type, they might be unnecessarily treated as having conflicting definition names requiring resolution - -#### Removed -- Obsolete `TypeContext.getSchemaDefinitionName()` - -### `jsonschema-module-swagger-2` -#### Added -- Initial implementation of `Swagger2Module` for deriving schema attributes from OpenAPI `@Schema` annotations. - -### `jsonschema-maven-plugin` -#### Added -- Support for new `jsonschema-module-swagger-2` - -## [4.12.2] - 2020-06-10 -### `jsonschema-generator` -#### Fixed -- Performance: Cache looked-up getter in `FieldScope.findGetter()` -- Performance: Cache looked-up field in `MethodScope.findGetterField()` - -### `jsonschema-maven-plugin` -#### Fixed -- Collecting all classes from a given `` even if it contains classes whose super types are not included - -## [4.12.1] - 2020-05-28 -### `jsonschema-maven-plugin` -#### Fixed -- Setting correct contextual classpath for class/package look-up via reflections - -## [4.12.0] - 2020-05-10 -### `jsonschema-generator` -#### Added -- New `SchemaGeneratorGeneralConfigPart.withPropertySorter()` exposing the sorting logic of an object schema's properties - -### `jsonschema-module-jackson` -#### Added -- New `JacksonOption.RESPECT_JSONPROPERTY_ORDER` to sort properties in an object's schema based on `@JsonPropertyOrder` annotations -- New `JacksonOption.IGNORE_PROPERTY_NAMING_STRATEGY` to skip the adjustment of property names based on `@JsonNaming` annotations - -#### Changed -- Consider `@JsonNaming` annotations to alter the names of contained fields according to the specified `PropertyNamingStrategy` - -## [4.11.1] - 2020-04-30 -### `jsonschema-maven-plugin` -#### Fixed -- Maven plugin is unable to resolve runtime dependencies (#95) - -## [4.11.0] - 2020-04-28 -### `jsonschema-generator` -#### Added -- New `Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES` to include `additionalProperties` with a schema for each `Map`'s value type `V` -- New `Option.DEFINITION_FOR_MAIN_SCHEMA` to allow moving main/target schema into `definitions`/`$defs` -- New `Option.PLAIN_DEFINITION_KEYS` to ensure keys in `definitions`/`$defs` adhere to the reduced set of allowed characters expected by OpenAPI -- New `SchemaGenerator.buildMultipleSchemaDefinitions()` allowing to generate JSON Schema elements (e.g. for building an OpenAPI description) - -#### Fixed -- Skip fields for which `isFakeContainerItemScope()` returns `true`, when fulfilling value collection for `Option.VALUES_FROM_CONSTANT_FIELDS` -- Treat `Byte`/`byte` as `"type": "string"` and not as `"type": "integer"` by default - -### `jsonschema-maven-plugin` -#### Added -- Initial implementation -- Support schema generation from one or multiple classes -- Support schema generation for all classes in one or multiple packages -- Allow configuration of target schema version -- Allow configuration of `OptionPreset` (also allowing for `NONE`) -- Allow configuration of individual `Option`s to be enabled/disabled -- Allow configuration of standard modules by name, with possible list of module options -- Allow configuration of custom modules by class name - -## [4.10.0] - 2020-04-12 -### `jsonschema-generator` -#### Added -- Official support for Draft 6 (via new `SchemaVersion.DRAFT_6`) -- New `Option.INLINE_ALL_SCHEMAS` to enforce no `definitions`/`$defs` to be produced (throwing exception if there is at least one circular reference) -- Offering also `SchemaGenerationContext.createStandardDefinition(FieldScope, CustomPropertyDefinitionProvider)` -- Offering also `SchemaGenerationContext.createStandardDefinition(MethodScope, CustomPropertyDefinitionProvider)` -- Alternative `SchemaGenerationConfigPart.withInstanceAttributeOverride(InstanceAttributeOverrideV2)` with access to `SchemaGenerationContext` - -#### Changed -- Enhance `Option.ALLOF_CLEANUP_AT_THE_END` to also reduce `allOf` if multiple parts have the same attributes but with equal values (except for `if` tags) -- Providing access to the `SchemaGenerationContext` when invoking `TypeAttributeOverrideV2` (potentially BREAKING change in case of lambda usage) - -#### Deprecated -- `SchemaGenerationConfigPart.withInstanceAttributeOverride(InstanceAttributeOverride)` without access to `SchemaGenerationContext` -- `InstanceAttributeOverride` interface without access to `SchemaGenerationContext` -- `TypeAttributeOverride` interface with only access to `SchemaGenerationConfig` and not `SchemaGenerationContext` -- Ambiguous `SchemaGeneratorConfigBuilder.with(CustomDefinitionProviderV2)` -- Ambiguous and outdated `SchemaGeneratorConfigBuilder.with(TypeAttributeOverride)` - -### `jsonschema-module-jackson` -#### Added -- New `JacksonOption.FLATTENED_ENUMS_FROM_JSONPROPERTY` to allow enum serialization based on each constant's `@JsonProperty` value - -## [4.9.0] - 2020-04-02 -### `jsonschema-generator` -#### Added -- Convenience constructors on `SchemaGeneratorConfigBuilder` without explicit `ObjectMapper` instance being expected -- Convenience methods on `FieldScope`/`MethodScope` for accessing (first level) container item annotations: `getContainerItemAnnotation()` and `getContainerItemAnnotationConsideringFieldAndGetter()` - -#### Changed -- `MethodScope.getAnnotation()` now also considers annotations directly on return type (when no matching annotation was found on the method itself) - -#### Fixed -- Attributes set in custom property definitions should not be overridden by other configurations (except for explicit attribute overrides) - -### `jsonschema-module-javax-validation` -#### Changed -- Consider (first level) container item annotations (e.g. `List<@Size(min = 3) String>`) - -## [4.8.1] - 2020-03-31 -### All -#### Fixed -- Include parent `pom.xml` when publishing release - -### `jsonschema-module-swagger-1.5` -#### Fixed -- Error when encountering container/collection property - -## [4.8.0] - 2020-03-30 -### `jsonschema-generator` -#### Added -- Support for custom definitions in the scope of a particular field/method via `SchemaGeneratorConfigPart.withCustomDefinitionProvider()` -- Ability to opt-out of normal "attribute collection" for custom definitions through new `CustomDefinition` constructor parameters - -#### Changed -- Consolidate `anyOf` entries that only contain an `anyOf` themselves into the outer `anyOf` (mostly relevant for nullable entries with subtypes) -- If a field/method is of a container type: apply the per-property configurations on its items; with `MemberScope.isFakeContainerItemScope()` flag - -#### Fixed -- Should consider per-type attributes even on inline custom definitions -- Use less strict `anyOf` instead of `oneOf` when indicating that a sub-schema may be of `"type": "null"` - -#### Dependency Update -- `com.fasterxml.jackson.core`:`jackson-core`/`jackson-databind` from `2.10.2` to `2.10.3` -- Remove dependencies to `log4j` implementation (only `slf4j-api` remains) - -### `jsonschema-module-jackson` -#### Added -- Look-up subtypes according to `@JsonTypeInfo` and `@JsonSubTypes` annotations per-type or overridden per-property: - - Considering `@JsonTypeInfo.include` with values `As.PROPERTY`, `As.EXISTING_PROPERTY`, `As.WRAPPER_ARRAY`, `As.WRAPPER_OBJECT` - - Considering `@JsonTypeInfo.use` with values `Id.NAME` (from `@JsonTypeName`) and `Id.CLASS` -- New `JacksonOption.SKIP_SUBTYPE_LOOKUP` for disabling the new look-up of subtypes (i.e. to regain previous behaviour) if required -- New `JacksonOption.IGNORE_TYPE_INFO_TRANSFORM` for disabling addition of extra property or wrapping in an array/object according to `@JsonTypeInfo` - -## [4.7.0] - 2020-03-20 -### `jsonschema-generator` -#### Added -- Support for multiple target type overrides at once per field/method -- Support for "$id" property via `SchemaGeneratorGeneralConfigPart.withIdResolver()` -- Support for "$anchor" property via `SchemaGeneratorGeneralConfigPart.withAnchorResolver()` - -#### Fixed -- Allow for multiple types with the same name (but different package) instead of picking one at random -- Allow for multiple definitions for the same type (e.g. in case of a custom definition wrapping the standard definition) - -#### Deprecated -- Configuration option for single target type override -- Look-up of single target type override from configuration - -### `jsonschema-module-jackson` -#### Changed -- Ignore/exclude properties marked with `@JsonBackReference` - -## [4.6.0] - 2020-03-15 -### `jsonschema-generator` -#### Added -- Explicit indication of targeted JSON Schema version (for now: Draft 7 or 2019-09) -- Support for renamed keywords between Draft versions through new `SchemaKeyword` enum (replacing static `SchemaConstants` interface) -- Support for `$ref` alongside other attributes (from Draft 2019-09 onwards) thereby reducing number of `allOf` elements -- Introduce `Option.ALLOF_CLEANUP_AT_THE_END` (also included in all standard `OptionPreset`s) for toggling-off this improvement if not desired - -#### Changed -- Reduce number of `allOf` elements in generated schema when contained schema parts are distinct (and in case of Draft 7: don't contain `$ref`) - -#### Deprecated -- `SchemaConstants` interface containing static `String` constants for tag names/values (in favour of version-aware `SchemaKeyword` enum) -- Internal `AttributeCollector` API without generation context as parameter -- `SchemaGeneratorConfigBuilder` constructors without explicit JSON Schema version indication - -#### Dependency Update -- `com.fasterxml.jackson.core`:`jackson-core`/`jackson-databind` from `2.10.0` to `2.10.2` -- `com.fasterxml`:`classmate` from `1.5.0` to `1.5.2` -- Optional: `org.slf4j`:`slf4j-api` from `1.7.26` to `1.7.30` -- Optional: `org.apache.logging.log4j`:`log4j-api`/`log4j-core`/`log4j-slf4j-impl` from `2.11.2` to `2.13.0` - -## [4.5.0] - 2020-03-05 -### `jsonschema-generator` -#### Added -- Expose `SchemaGenerationContext.createDefinitionReference()` to custom definitions to enable circular references within -- Expose `SchemaGenerationContext.createStandardDefinitionReference()` to custom definitions to enable circular references within - -### `jsonschema-module-jackson` -#### Added -- New `JacksonOption.FLATTENED_ENUMS_FROM_JSONVALUE` for considering `@JsonValue` annotations on enums, similar to `Option.FLATTENED_ENUMS` - -## [4.4.0] - 2020-03-02 -### `jsonschema-generator` -#### Added -- Enable declaration of subtypes through `withSubtypeResolver(SubtypeResolver)` on `forTypesInGeneral()` (#24) - -#### Changed -- Move custom definitions and type attribute overrides into `forTypesInGeneral()` (while preserving delegate setters on config builder) - -## [4.3.0] - 2020-02-28 -### `jsonschema-generator` -#### Changed -- Limit collected type attributes by declared "type" (prior to any `TypeAttributeOverride`!) - -#### Fixed -- Not declare any "type" for `Object.class` by default - -## [4.2.0] - 2020-02-27 -### `jsonschema-generator` -#### Added -- Support for "additionalProperties" property via `SchemaGeneratorTypeConfigPart.withAdditionalPropertiesResolver()` -- Support for "patternProperties" property via `SchemaGeneratorTypeConfigPart.withPatternPropertiesResolver()` -- Introduce new `Option.FORBIDDEN_ADDITIONAL_PROPERTIES_BY_DEFAULT` for more convenient usage -- Offer `TypeScope.getTypeParameterFor()` and `TypeContext.getTypeParameterFor()` convenience methods - -#### Fixed -- Possible exceptions in case of encountered collections without specific type parameters - -## [4.1.0] - 2020-02-18 -### `jsonschema-generator` -#### Added -- New `Option.FLATTENED_ENUMS_FROM_TOSTRING`, using `toString()` instead of `name()` as per `Option.FLATTENED_ENUMS` - -## [4.0.2] - 2020-01-30 -### `jsonschema-generator` -#### Fixed -- Avoid further characters in definition keys that are not URI-compatible (#19) - -## [4.0.1] - 2020-01-29 -### `jsonschema-generator` -#### Fixed -- Avoid white-spaces in definition keys - -## [4.0.0] - 2020-01-03 -### `jsonschema-generator` -#### Added -- Extended API for defining context independent collection of schema attributes (for array/collection items that are not directly under a member) - -#### Changed -- BREAKING CHANGE: `TypeAttributeOverride`'s second parameter is now the new `TypeScope` wrapper instead of just a `ResolvedType` - -### `jsonschema-module-jackson` -#### Changed -- Look-up descriptions from `@JsonClassDescription` via new `forTypesInGeneral()` API - -### `jsonschema-module-swagger-1.5` -#### Changed -- Look-up titles and descriptions from `@ApiModel` via new `forTypesInGeneral()` API - -## [3.5.0] - 2020-01-01 -### `jsonschema-generator` -#### Added -- `CustomDefinitionProviderV2` with access to `SchemaGenerationContext`, e.g. to allow continuing normal schema generation for nested properties - -#### Deprecated -- `CustomDefinitionProvider` receiving only the `TypeContext` as parameter - -#### Fixed -- Possible `IllegalAccess` when loading constant values should just be ignored - -## [3.4.1] - 2019-12-30 -### `jsonschema-generator` -#### Fixed -- Collected attributes should also be applied to container types (Issue #15) - -## [3.4.0] - 2019-11-29 -### `jsonschema-generator` -#### Added -- Introduce convenience function `MemberScope.getAnnotationConsideringFieldAndGetter(Class)` - -### `jsonschema-module-swagger-1.5` -#### Added -- Optionally provide a field/method's "title" as per `@ApiModel(value = ...)` -- Allow to ignore the general `@ApiModel(description = ...)` when populating a field/method's "description" - -## [3.3.0] - 2019-10-25 -### `jsonschema-generator` -#### Fixed -- Increase dependency version for jackson-databind (and jackson-core) to resolve security alerts. -- Avoid unnecessary quotes when representing constant string values (due to changed behaviour in jackson >=2.10.0) - -## [3.2.0] – 2019-09-01 -### `jsonschema-generator` -#### Added -- In `SchemaGenerator.generateSchema(Type)` also allow passing type parameters via `SchemaGenerator.generateSchema(Type, Type...)`. -- Support for "required" property via `SchemaGeneratorConfigPart.withRequiredCheck()` (PR #5). -- Support for "default" property via `SchemaGeneratorConfigPart.withDefaultResolver()` (PR #5). -- Support for "pattern" property via `SchemaGeneratorConfigPart.withStringPatternResolver()` (Issue #9). - -### `jsonschema-module-javax-validation` -#### Added -- Option for treating not-nullable fields as "required" in their parent type -- Option for treating not-nullable methods as "required" in their parent type -- Indicate a string's "format" to be "email" if `@Email` is present -- Option for returning "idn-email" instead of "email" as "format" if `@Email` is present -- Indicate a string's "pattern" according to regular expressions on `@Pattern` or `@Email` (ignoring specified flags) -- Option for enabling the inclusion of "pattern" expressions (they are excluded by default) -- Allow filtering applicable annotations by their declared validation `groups` via `JavaxValidationModule.forValidationGroups()` - -## [3.1.0] – 2019-06-18 -### `jsonschema-generator` -#### Changed -- Use `Class.getTypeName()` instead of `Class.getName()` in `TypeContext.getFullTypeDescription()`. - -#### Added -- In `TypeContext.resolve(Type)` also allow passing type parameters via `TypeContext.resolve(Type, Type...)`. - -#### Fixed -- `NullPointerException` on `MemberScope` representing `void` methods. -- `IndexOutOfBoundsException` when determining container item type of raw `Collection`. - -## [3.0.0] – 2019-06-10 -### `jsonschema-generator` -#### Changed -- Simplify configuration API to be based on `FieldScope`/`MethodScope` respectively. -- Consolidate some utility functions into `FieldScope`/`MethodScope`. -- Consolidate logic for determining whether a type is a container into `TypeContext`. -- Consolidate naming logic for schema "definitions" into `TypeContext`. -- Add `TypeContext` argument to `CustomDefinitionProvider` interface. -- Remove `SchemaGeneratorConfig` argument from `InstanceAttributeOverride` interface. - -#### Added -- Allow for sub-typing of `FieldScope`/`MethodScope` and `TypeContext` (in case offered configuration options are insufficient). - -#### Removed -- Remove support for `Option.GETTER_ATTRIBUTES_FOR_FIELDS` and `Option.FIELD_ATTRIBUTES_FOR_GETTERS`, rather let configurations/modules decide individually and avoid potential endless loop. - -### `jsonschema-module-jackson` -#### Added -- Populate "description" as per `@JsonPropertyDescription` (falling-back on `@JsonClassDescription`). -- Apply alternative field names defined in `@JsonProperty` annotations. -- Ignore fields that are deemed to be ignored according to various `jackson-annotations` (e.g. `@JsonIgnore`, `@JsonIgnoreType`, `@JsonIgnoreProperties`) or are otherwise supposed to be excluded. - -### `jsonschema-module-javax-validation` -#### Added -- Consider the same validation annotations on a getter method also for its field -- Consider the same validation annotations on a field also for its getter method - -### `jsonschema-module-swagger-1.5` -#### Added -- Optionally override a field's property name with `@ApiModelProperty(name = ...)` -- Optionally ignore a field/method if `@ApiModelProperty(hidden = true)` -- Provide a field/method's "description" as per `@ApiModelProperty(value = ...)` or `@ApiModel(description = ...)` -- Indicate a number's (field/method) "minimum" (inclusive) according to `@ApiModelProperty(allowableValues = "range[...")` -- Indicate a number's (field/method) "exclusiveMinimum" according to `@ApiModelProperty(allowableValues = "range(...")` -- Indicate a number's (field/method) "maximum" (inclusive) according to `@ApiModelProperty(allowableValues = "range...]")` -- Indicate a number's (field/method) "exclusiveMaximum" according to `@ApiModelProperty(allowableValues = "range...)")` -- Indicate a field/method's "const"/"enum" as `@ApiModelProperty(allowableValues = ...)` (if it is not a numeric range declaration) -- Consider the `@ApiModelProperty` annotation on a getter method also for its field -- Consider the `@ApiModelProperty` annotation on a field also for its getter method - -## [2.0.0] – 2019-06-07 -### `jsonschema-generator` -#### Changed -- Removed type resolution and replaced it with `org.fasterxml:classmate` dependency. -- Adjusting configuration API to use `classmate` references for types/fields/methods. - -#### Fixed -- Ignore complex constant values that may not be properly representable as JSON. - -## [1.0.2] - 2019-05-30 -### `jsonschema-generator` -#### Fixed -- Increase dependency version for jackson-databind to resolve security alert. - -## [1.0.1] - 2019-05-19 -### `jsonschema-generator` -#### Fixed -- Specified "test" scope for dependency on jsonassert. - -## [1.0.0] - 2019-05-18 -### `jsonschema-generator` -#### Added -- Reflection-based JSON Schema Generator. -- Support of generics and the resolution of their type boundaries in the respective scope. -- Inclusion of any fields and public methods in a generated JSON Schema. -- Ability to define a fixed JSON Schema per type (e.g. for determining how to represent primitive types). -- Ability to customise various aspects of schema generation and assigned attributes. -- Concept of modules (e.g. for sub-libraries) to define a single entry-point for applying individual configurations. -- Standard enum of common configuration options. -- Specific handling of enums (two alternatives via standard options). -- Specific handling of optionals (two alternatives via standard options). -- Pre-defined sets of standard options to cover different use-cases and simplify library usage. - -### `jsonschema-module-javax-validation` -#### Added -- Indicate a field/method to be nullable if `@Null` is present -- Indicate a field/method to be not nullable if `@NotNull`, `@NotEmpty` or `@NotBlank` is present -- Indicate an array's "minItems" according to `@Size` or `@NotEmpty` -- Indicate an array's "maxItems" according to `@Size` -- Indicate a string's "minLength" according to `@Size`, `@NotEmpty` or `@NotBlank` -- Indicate a string's "maxLength" according to `@Size` -- Indicate a number's "minimum" (inclusive) according to `@Min`, `@DecimalMin` or `@PositiveOrZero` -- Indicate a number's "exclusiveMinimum" according to `@DecimalMin` or `@Positive` -- Indicate a number's "maximum" (inclusive) according to `@Max`, `@DecimalMax` or `@NegativeOrZero` -- Indicate a number's "exclusiveMaximum" according to `@DecimalMax` or `@Negative` - - -[Unreleased]: https://github.com/victools/jsonschema-generator/compare/v4.38.0...HEAD -[4.38.0]: https://github.com/victools/jsonschema-generator/compare/v4.37.0...v4.38.0 -[4.37.0]: https://github.com/victools/jsonschema-generator/compare/v4.36.0...v4.37.0 -[4.36.0]: https://github.com/victools/jsonschema-generator/compare/v4.35.0...v4.36.0 -[4.35.0]: https://github.com/victools/jsonschema-generator/compare/v4.34.0...v4.35.0 -[4.34.0]: https://github.com/victools/jsonschema-generator/compare/v4.33.1...v4.34.0 -[4.33.1]: https://github.com/victools/jsonschema-generator/compare/v4.33.0...v4.33.1 -[4.33.0]: https://github.com/victools/jsonschema-generator/compare/v4.32.0...v4.33.0 -[4.32.0]: https://github.com/victools/jsonschema-generator/compare/v4.31.1...v4.32.0 -[4.31.1]: https://github.com/victools/jsonschema-generator/compare/v4.31.0...v4.31.1 -[4.31.0]: https://github.com/victools/jsonschema-generator/compare/v4.30.0...v4.31.0 -[4.30.0]: https://github.com/victools/jsonschema-generator/compare/v4.29.0...v4.30.0 -[4.29.0]: https://github.com/victools/jsonschema-generator/compare/v4.28.0...v4.29.0 -[4.28.0]: https://github.com/victools/jsonschema-generator/compare/v4.27.0...v4.28.0 -[4.27.0]: https://github.com/victools/jsonschema-generator/compare/v4.26.0...v4.27.0 -[4.26.0]: https://github.com/victools/jsonschema-generator/compare/v4.25.0...v4.26.0 -[4.25.0]: https://github.com/victools/jsonschema-generator/compare/v4.24.3...v4.25.0 -[4.24.3]: https://github.com/victools/jsonschema-generator/compare/v4.24.2...v4.24.3 -[4.24.2]: https://github.com/victools/jsonschema-generator/compare/v4.24.1...v4.24.2 -[4.24.1]: https://github.com/victools/jsonschema-generator/compare/v4.24.0...v4.24.1 -[4.24.0]: https://github.com/victools/jsonschema-generator/compare/v4.23.0...v4.24.0 -[4.23.0]: https://github.com/victools/jsonschema-generator/compare/v4.22.0...v4.23.0 -[4.22.0]: https://github.com/victools/jsonschema-generator/compare/v4.21.0...v4.22.0 -[4.21.0]: https://github.com/victools/jsonschema-generator/compare/v4.20.0...v4.21.0 -[4.20.0]: https://github.com/victools/jsonschema-generator/compare/v4.19.0...v4.20.0 -[4.19.0]: https://github.com/victools/jsonschema-generator/compare/v4.18.0...v4.19.0 -[4.18.0]: https://github.com/victools/jsonschema-generator/compare/v4.17.0...v4.18.0 -[4.17.0]: https://github.com/victools/jsonschema-generator/compare/v4.16.0...v4.17.0 -[4.16.0]: https://github.com/victools/jsonschema-generator/compare/v4.15.1...v4.16.0 -[4.15.1]: https://github.com/victools/jsonschema-generator/compare/v4.15.0...v4.15.1 -[4.15.0]: https://github.com/victools/jsonschema-generator/compare/v4.14.0...v4.15.0 -[4.14.0]: https://github.com/victools/jsonschema-generator/compare/v4.13.0...v4.14.0 -[4.13.0]: https://github.com/victools/jsonschema-generator/compare/v4.12.2...v4.13.0 -[4.12.2]: https://github.com/victools/jsonschema-generator/compare/v4.12.1...v4.12.2 -[4.12.1]: https://github.com/victools/jsonschema-generator/compare/v4.12.0...v4.12.1 -[4.12.0]: https://github.com/victools/jsonschema-generator/compare/v4.11.1...v4.12.0 -[4.11.1]: https://github.com/victools/jsonschema-generator/compare/v4.11.0...v4.11.1 -[4.11.0]: https://github.com/victools/jsonschema-generator/compare/v4.10.0...v4.11.0 -[4.10.0]: https://github.com/victools/jsonschema-generator/compare/v4.9.0...v4.10.0 -[4.9.0]: https://github.com/victools/jsonschema-generator/compare/v4.8.1...v4.9.0 -[4.8.1]: https://github.com/victools/jsonschema-generator/compare/v4.8.0...v4.8.1 -[4.8.0]: https://github.com/victools/jsonschema-generator/compare/v4.7.0...v4.8.0 -[4.7.0]: https://github.com/victools/jsonschema-generator/compare/v4.6.0...v4.7.0 -[4.6.0]: https://github.com/victools/jsonschema-generator/compare/v4.5.0...v4.6.0 -[4.5.0]: https://github.com/victools/jsonschema-generator/compare/v4.4.0...v4.5.0 -[4.4.0]: https://github.com/victools/jsonschema-generator/compare/v4.3.0...v4.4.0 -[4.3.0]: https://github.com/victools/jsonschema-generator/compare/v4.2.0...v4.3.0 -[4.2.0]: https://github.com/victools/jsonschema-generator/compare/v4.1.0...v4.2.0 -[4.1.0]: https://github.com/victools/jsonschema-generator/compare/v4.0.2...v4.1.0 -[4.0.2]: https://github.com/victools/jsonschema-generator/compare/v4.0.1...v4.0.2 -[4.0.1]: https://github.com/victools/jsonschema-generator/compare/v4.0.0...v4.0.1 -[4.0.0]: https://github.com/victools/jsonschema-generator/compare/v3.5.0...v4.0.0 -[3.5.0]: https://github.com/victools/jsonschema-generator/compare/v3.4.1...v3.5.0 -[3.4.1]: https://github.com/victools/jsonschema-generator/compare/v3.4.0...v3.4.1 -[3.4.0]: https://github.com/victools/jsonschema-generator/compare/v3.3.0...v3.4.0 -[3.3.0]: https://github.com/victools/jsonschema-generator/compare/v3.2.0...v3.3.0 -[3.2.0]: https://github.com/victools/jsonschema-generator/compare/v3.1.0...v3.2.0 -[3.1.0]: https://github.com/victools/jsonschema-generator/compare/v3.0.0...v3.1.0 -[3.0.0]: https://github.com/victools/jsonschema-generator/compare/v2.0.0...v3.0.0 -[2.0.0]: https://github.com/victools/jsonschema-generator/compare/v1.0.2...v2.0.0 -[1.0.2]: https://github.com/victools/jsonschema-generator/compare/v1.0.1...v1.0.2 -[1.0.1]: https://github.com/victools/jsonschema-generator/compare/v1.0.0...v1.0.1 -[1.0.0]: https://github.com/victools/jsonschema-generator/releases/tag/v1.0.0 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md deleted file mode 100644 index bb78ddf1..00000000 --- a/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# Java JSON Schema Generator -[![Build Status](https://github.com/victools/jsonschema-generator/workflows/Java%20CI%20(Maven)/badge.svg)](https://github.com/victools/jsonschema-generator/actions?query=workflow%3A%22Java+CI+%28Maven%29%22) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.victools/jsonschema-generator/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.victools/jsonschema-generator) - -Creating JSON Schema (Draft 6, Draft 7, Draft 2019-09 or Draft 2020-12) from your Java classes utilising Jackson. - ----- - -This project consists of: -- the [victools/jsonschema-generator](jsonschema-generator) (the only thing you need to get started) -- a few modules bundling standard configurations for your convenience: - - [victools/jsonschema-module-jackson](jsonschema-module-jackson) – deriving JSON Schema attributes from `jackson` annotations (e.g. "description", property name overrides, what properties to ignore) as well as looking up appropriate (annotated) subtypes - - [victools/jsonschema-module-jakarta-validation](jsonschema-module-jakarta-validation) – deriving JSON Schema attributes from `jakarta.validation.constraints` annotations (e.g. which properties are nullable or not, their "minimum"/"maximum", "minItems"/"maxItems", "minLength"/"maxLength") - - [victools/jsonschema-module-javax-validation](jsonschema-module-javax-validation) – deriving JSON Schema attributes from `javax.validation` annotations (e.g. which properties are nullable or not, their "minimum"/"maximum", "minItems"/"maxItems", "minLength"/"maxLength") - - [victools/jsonschema-module-swagger-1.5](jsonschema-module-swagger-1.5) – deriving JSON Schema attributes from `swagger` (1.5.x) annotations (e.g. "description", property name overrides, what properties to ignore, their "minimum"/"maximum", "const"/"enum") - - [victools/jsonschema-module-swagger-2](jsonschema-module-swagger-2) – deriving JSON Schema attributes from `swagger` (2.x) `@Schema` annotations -- the [victools/jsonschema-maven-plugin](jsonschema-maven-plugin) – allowing you to generate JSON Schemas as part of your Maven build - -Another example for such a module is: -- [imIfOu/jsonschema-module-addon](https://github.com/imIfOu/jsonschema-module-addon) – deriving JSON Schema attributes from a custom annotation with various parameters, which is part of the module. - ----- - -## Documentation -JavaDoc is being used throughout the codebase, offering contextual information in your respective IDE or being available online through services like [javadoc.io](https://www.javadoc.io/doc/com.github.victools/jsonschema-generator). - -Additional documentation and configuration examples can be found here: https://victools.github.io/jsonschema-generator - ----- - -## Usage -### Dependency (Maven) - -```xml - - com.github.victools - jsonschema-generator - 4.38.0 - -``` - -Since version `4.7`, the release versions of the main generator library and the (standard) `victools` modules listed above are aligned. -It is recommended to use identical versions for all of them to ensure compatibility. - -It is discouraged to use an older/lower `jsonschema-generator` version than any of your `jsonschema-module-*` dependencies. If the module uses any feature only added to the `jsonschema-generator` in the newer version, runtime errors are to be expected. - -### Code -#### Complete/Minimal Example -```java -import com.fasterxml.jackson.databind.JsonNode; -import com.github.victools.jsonschema.generator.OptionPreset; -import com.github.victools.jsonschema.generator.SchemaGenerator; -import com.github.victools.jsonschema.generator.SchemaGeneratorConfig; -import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder; -import com.github.victools.jsonschema.generator.SchemaVersion; -``` -```java -SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2020_12, OptionPreset.PLAIN_JSON); -SchemaGeneratorConfig config = configBuilder.build(); -SchemaGenerator generator = new SchemaGenerator(config); -JsonNode jsonSchema = generator.generateSchema(YourClass.class); - -System.out.println(jsonSchema.toPrettyString()); -``` - -Additional examples can be found in the [jsonschema-examples](jsonschema-examples) folder or throughout the various tests classes. diff --git a/checkstyle.xml b/checkstyle.xml deleted file mode 100644 index c9b3956b..00000000 --- a/checkstyle.xml +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/slate-docs/source/fonts/slate.ttf b/fonts/slate-7b7da4fe.ttf similarity index 100% rename from slate-docs/source/fonts/slate.ttf rename to fonts/slate-7b7da4fe.ttf diff --git a/slate-docs/source/fonts/slate.eot b/fonts/slate-cfc9d06b.eot similarity index 100% rename from slate-docs/source/fonts/slate.eot rename to fonts/slate-cfc9d06b.eot diff --git a/slate-docs/source/fonts/slate.svg b/fonts/slate-e55b8307.svg similarity index 100% rename from slate-docs/source/fonts/slate.svg rename to fonts/slate-e55b8307.svg diff --git a/slate-docs/source/fonts/slate.woff b/fonts/slate.woff similarity index 100% rename from slate-docs/source/fonts/slate.woff rename to fonts/slate.woff diff --git a/slate-docs/source/fonts/slate.woff2 b/fonts/slate.woff2 similarity index 100% rename from slate-docs/source/fonts/slate.woff2 rename to fonts/slate.woff2 diff --git a/slate-docs/source/images/logo.png b/images/logo-fd04e752.png similarity index 100% rename from slate-docs/source/images/logo.png rename to images/logo-fd04e752.png diff --git a/slate-docs/source/images/navbar.png b/images/navbar-cad8cdcb.png similarity index 100% rename from slate-docs/source/images/navbar.png rename to images/navbar-cad8cdcb.png diff --git a/index.html b/index.html new file mode 100644 index 00000000..a54b2ef8 --- /dev/null +++ b/index.html @@ -0,0 +1,2458 @@ + + + + + + + + API Reference + + + + + + + + + + + + + + NAV + + + +
+ + +
    + + +
    +
    +
    +
    +

    Introduction

    +

    The victools/jsonschema-generator repository is home to multiple artifacts that are published independently to "The Central Repository" (Sonatype) and from there to others like "Maven Central". +Besides the main generator library itself, there are a few modules providing some standard configurations for your convenience.

    + + + +

    This documentation aims at always covering the latest released version of the jsonschema-generator and its (standard) modules. There is no documentation for previous versions at this stage. +Please refer to the CHANGELOG for a list of the incremental changes.

    + +
    + +

    The victools:jsonschema-generator aims at allowing the generation of JSON Schema (Draft 6, Draft 7, Draft 2019-09 or Draft 2020-12) to document Java code. +This is expressly not limited to JSON but also allows for a Java API to be documented (i.e. including methods and the associated return values).

    +

    Generator – Options

    +

    The schema generation caters for a certain degree of flexibility out-of-the-box.
    +Various aspects can be toggled on/off by including or excluding respective Options.

    +
    configBuilder.with(
    +    Option.EXTRA_OPEN_API_FORMAT_VALUES,
    +    Option.PLAIN_DEFINITION_KEYS);
    +configBuilder.without(
    +    Option.Schema_VERSION_INDICATOR,
    +    Option.ENUM_KEYWORD_FOR_SINGLE_VALUES);
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Behavior if includedBehavior if excluded
    1Option.SCHEMA_VERSION_INDICATOR
    Setting appropriate $schema attribute on main schema being generated.No $schema attribute is being added.
    2Option.ADDITIONAL_FIXED_TYPES
    +
      +
    • String/Character/char/CharSequence are treated as { "type": "string" } schema
    • +
    • Boolean/boolean are treated as { "type": "boolean" } schema
    • +
    • Integer/int/Long/long/Short/short/Byte/byte are treated as { "type": "integer" } schema
    • +
    • Double/double/Float/float are treated as { "type": "number" } schema
    • +
    • BigInteger as { "type": "integer" } schema
    • +
    • BigDecimal/Number as { "type": "number" } schema
    • +
    • LocalDate/LocalDateTime/LocalTime/ZonedDateTime/OffsetDateTime/OffsetTime/Instant/Period/ZoneId/Date/Calendar/UUID as { "type": "string" } schema
    • +
    +
    +
      +
    • String/Character/char/CharSequence are treated as { "type": "string" } schema
    • +
    • Boolean/boolean are treated as { "type": "boolean" } schema
    • +
    • Integer/int/Long/long/Short/short/Byte/byte are treated as { "type": "integer" } schema
    • +
    • Double/double/Float/float are treated as { "type": "number" } schema
    • +
    +
    3Option.STANDARD_FORMATS
    Subset of the "format" values being added by Option.EXTRA_OPEN_API_FORMAT_VALUES but limited to built-in supported "format" values ("date", "time", "date-time", "duration", "uuid", "uri"). + Only works if Option.ADDITIONAL_FIXED_TYPES is set. and it is overriden by Option.EXTRA_OPEN_API_FORMAT_VALUESno automatic "format" values are being included, unless Option.EXTRA_OPEN_API_FORMAT_VALUES indicates otherwise.
    4Option.EXTRA_OPEN_API_FORMAT_VALUES
    Include extra "format" values (e.g. "int32", "int64", "date", "time", "date-time", "duration", "uuid", "uri") for fixed types (primitive/basic types, plus some of the Option.ADDITIONAL_FIXED_TYPES if they are enabled as well). It overrides Option.STANDARD_FORMATS, which would cover only a subset of the OpenAPI format values.no automatic "format" values are being included, unless Option.STANDARD_FORMATS indicates otherwise.
    #Behavior if includedBehavior if excluded
    5Option.SIMPLIFIED_ENUMS
    Treating encountered enum types as objects, but including only the name() method and listing the names of the enum constants as its enum values.-
    6Option.FLATTENED_ENUMS
    Treating encountered enum types as { "type": "string" } schema with the names of the enum constants being listed as its enum values.-
    7Option.FLATTENED_ENUMS_FROM_TOSTRING
    Treating encountered enum types as { "type": "string" } schema with the toString() values of the enum constants being listed as its enum values.-
    8Option.SIMPLIFIED_OPTIONALS
    Treating encountered Optional instances as objects, but including only the get(), orElse() and isPresent() methods.-
    #Behavior if includedBehavior if excluded
    9Option.FLATTENED_OPTIONALS
    Replacing encountered Optional instances as null-able forms of their generic parameter type.-
    10Option.FLATTENED_SUPPLIERS
    Replacing encountered Supplier instances with their generic parameter type.-
    11Option.VALUES_FROM_CONSTANT_FIELDS
    + Attempt to load the values of static final fields, serialize them via the ObjectMapper and include them as the respective schema's const value. +
    For this option to take effect, those static final fields need to be included via Option.PUBLIC_STATIC_FIELDS and/or Option.NONPUBLIC_STATIC_FIELDS.
    +
    No const values are populated for static final fields.
    12Option.PUBLIC_STATIC_FIELDS
    Include public static fields in an object's properties.No public static fields are included in an object's properties.
    #Behavior if includedBehavior if excluded
    13Option.PUBLIC_NONSTATIC_FIELDS
    Include public non-static fields in an object's properties.No public non-static fields are included in an object's properties.
    14Option.NONPUBLIC_STATIC_FIELDS
    Include protected/package-visible/private static fields in an object's properties.No protected/package-visible/private static fields are included in an object's properties.
    15Option.NONPUBLIC_NONSTATIC_FIELDS_WITH_GETTERS
    Include protected/package-visible/private non-static fields in an object's properties if they have corresponding getter methods.No protected/package-visible/private non-static fields with getter methods are included in an object's properties.
    16Option.NONPUBLIC_NONSTATIC_FIELDS_WITHOUT_GETTERS
    Include protected/package-visible/private non-static fields in an object's properties if they don't have corresponding getter methods.No protected/package-visible/private non-static fields without getter methods are included in an object's properties.
    #Behavior if includedBehavior if excluded
    17Option.TRANSIENT_FIELDS
    Include transient fields in an object's properties if they would otherwise be included according to the Options above.No transient fields are included in an object's properties even if they would otherwise be included according to the Options above.
    18Option.STATIC_METHODS
    Include public static methods in an object's propertiesNo static methods are included in an object's properties even if they would be included according to the Option.VOID_METHODS below.
    19Option.VOID_METHODS
    Include public void methods in an object's propertiesNo void methods are included in an object's properties even if they would be included according to the Option.STATIC_METHODS above.
    20Option.GETTER_METHODS
    Include public methods in an object's properties if a corresponding field exists that fulfills the usual naming conventions (getX()/x or isValid()/valid).No methods are included in an object's properties> for which a field exists that fulfills the usual naming conventions.
    #Behavior if includedBehavior if excluded
    21Option.NONSTATIC_NONVOID_NONGETTER_METHODS
    Include public non-static non-void methods in an object's properties for which no field exists that fulfills the usual getter naming conventions.No non-static/non-void/non-getter methods are included in an object's properties.
    22Option.NULLABLE_FIELDS_BY_DEFAULT
    The schema type for a field allows null by default unless some configuration specifically says it is not null-able.The schema type for a field does not allow for null by default unless some configuration specifically says it is null-able.
    23Option.NULLABLE_METHOD_RETURN_VALUES_BY_DEFAULT
    The schema type for a method's return type allows null by default unless some configuration specifically says it is not null-able.The schema type for a method's return type does not allow for null by default unless some configuration specifically says it is null-able.
    24Option.NULLABLE_ARRAY_ITEMS_ALLOWED
    The schema type for the items in an array (in case of a field's value or method's return value being a container/array) allows null, if the corresponding configuration explicitly says so. Otherwise, they're still deemed not null-able by default.The schema type for the items in an array (in case of a field's value or method's return value being a container/array) never allows null.
    #Behavior if includedBehavior if excluded
    25Option.FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS
    Include argument-free methods as fields, e.g. the return type of getName() will be included as name field.Argument-free methods will be included with the appended parentheses.
    26Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES
    Setting the additionalProperties attribute in each Map<K, V> to a schema representing the declared value type V.Omitting the additionalProperties attribute in Map<K, V> schemas by default (thereby allowing additional properties of any type) unless some configuration specifically says something else.
    27Option.ACCEPT_SINGLE_VALUE_AS_ARRAY
    Including an anyOf for every field/method declaring a container type. The anyOf then allows for either the array as declared or just a single item type instead.A container type will be represented by an array with the declared item type.
    28Option.ENUM_KEYWORD_FOR_SINGLE_VALUES
    Using the enum keyword for allowed values, even if there is only one.In case of a single allowed value, use the const keyword instead of enum.
    #Behavior if includedBehavior if excluded
    29Option.FORBIDDEN_ADDITIONAL_PROPERTIES_BY_DEFAULT
    Setting the additionalProperties attribute in all object schemas to false by default unless some configuration specifically says something else.Omitting the additionalProperties attribute in all object schemas by default (thereby allowing any additional properties) unless some configuration specifically says something else.
    30Option.DEFINITIONS_FOR_ALL_OBJECTS
    Include an entry in the $defs/definitions for each encountered object type that is not explicitly declared as "inline" via a custom definition.Only include those entries in the $defs/definitions for object types that are referenced more than once and which are not explicitly declared as "inline" via a custom definition.
    31Option.DEFINITION_FOR_MAIN_SCHEMA
    Include an entry in the $defs/definitions for the main/target type and a corresponding $ref on the top level (which is only valid from Draft 2019-09 onward).Define the main/target type "inline".
    32Option.DEFINITIONS_FOR_MEMBER_SUPERTYPES
    For a member (field/method), having a declared type for which subtypes are being detected, include a single definition with any collected member attributes assigned directly. Any subtypes are only being handled as generic types, i.e., outside of the member context. That means, certain relevant annotations may be ignored (e.g. a jackson @JsonTypeInfo override on a single member would not be correctly reflected in the produced schema).For a member (field/method), having a declared type for which subtypes are being detected, include a list of definittions: one for each subtype in the given member's context. This allows independently interpreting contextual information (e.g., member annotations) for each subtype.
    #Behavior if includedBehavior if excluded
    33Option.INLINE_ALL_SCHEMAS
    Do not include any $defs/definitions but rather define all sub-schemas "inline" – however, this results in an exception being thrown if the given type contains any kind of circular reference.Depending on whether DEFINITIONS_FOR_ALL_OBJECTS is included or excluded.
    34Option.INLINE_NULLABLE_SCHEMAS
    Do not include $defs/definitions for a nullable version of a type, but rather define it "inline". The non-nullable type may still be referenced.Depending on whether DEFINITIONS_FOR_ALL_OBJECTS is included or excluded.
    35Option.PLAIN_DEFINITION_KEYS
    Ensure that the keys for any $defs/definitions match the regular expression ^[a-zA-Z0-9\.\-_]+$ (as expected by the OpenAPI specification 3.0).Ensure that the keys for any $defs/definitions are URI compatible (as expected by the JSON Schema specification).
    36Option.ALLOF_CLEANUP_AT_THE_END
    At the very end of the schema generation reduce allOf wrappers where it is possible without overwriting any attributes – this also affects the results from custom definitions.Do not attempt to reduce allOf wrappers but preserve them as they were generated regardless of them being necessary or not.
    #Behavior if includedBehavior if excluded
    37Option.STRICT_TYPE_INFO
    As final step in the schema generation process, ensure all sub schemas containing keywords implying a particular "type" (e.g., "properties" implying an "object") have this "type" declared explicitly – this also affects the results from custom definitions.No additional "type" indication will be added for each sub schema, e.g. on the collected attributes where the "allOf" clean-up could not be applied or was disabled.
    38Option.NULLABLE_ALWAYS_AS_ANYOF
    A "type": "null" will not be combined with other "type" values in an array. Instead, a separate "anyOf" with a subschema only containing the "type": "null" will be included.For brevity's sake, a "type": "null" may be combined with other "type" values, e.g. as "type": ["null", "object"].
    + +

    Below, you can find the lists of Options included/excluded in the respective standard OptionPresets:

    + +
      +
    • "F_D" = FULL_DOCUMENTATION
    • +
    • "J_O" = JAVA_OBJECT
    • +
    • "P_J" = PLAIN_JSON
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Standard OptionF_DJ_OP_J
    1SCHEMA_VERSION_INDICATOR⬜️⬜️
    2ADDITIONAL_FIXED_TYPES⬜️⬜️
    3STANDARD_FORMATS⬜️
    4EXTRA_OPEN_API_FORMAT_VALUES⬜️⬜️⬜️
    5SIMPLIFIED_ENUMS⬜️
    6FLATTENED_ENUMS⬜️⬜️
    7FLATTENED_ENUMS_FROM_TOSTRING⬜️⬜️⬜️
    8SIMPLIFIED_OPTIONALS⬜️
    9FLATTENED_OPTIONALS⬜️⬜️
    10FLATTENED_SUPPLIERS⬜️⬜️
    11VALUES_FROM_CONSTANT_FIELDS
    12PUBLIC_STATIC_FIELDS⬜️
    13PUBLIC_NONSTATIC_FIELDS
    14NONPUBLIC_STATIC_FIELDS⬜️⬜️
    15NONPUBLIC_NONSTATIC_FIELDS_WITH_GETTERS⬜️
    16NONPUBLIC_NONSTATIC_FIELDS_WITHOUT_GETTERS⬜️
    17TRANSIENT_FIELDS⬜️⬜️
    18STATIC_METHODS⬜️
    19VOID_METHODS⬜️
    20GETTER_METHODS⬜️
    21NONSTATIC_NONVOID_NONGETTER_METHODS⬜️
    22NULLABLE_FIELDS_BY_DEFAULT⬜️⬜️
    23NULLABLE_METHOD_RETURN_VALUES_BY_DEFAULT⬜️⬜️
    24NULLABLE_ARRAY_ITEMS_ALLOWED⬜️⬜️⬜️
    25FIELDS_DERIVED_FROM_ARGUMENTFREE_METHODS⬜️⬜️⬜️
    26MAP_VALUES_AS_ADDITIONAL_PROPERTIES⬜️⬜️⬜️
    27ACCEPT_SINGLE_VALUE_AS_ARRAY⬜️⬜️⬜️
    28ENUM_KEYWORD_FOR_SINGLE_VALUES⬜️⬜️⬜️
    29FORBIDDEN_ADDITIONAL_PROPERTIES_BY_DEFAULT⬜️⬜️⬜️
    30DEFINITIONS_FOR_ALL_OBJECTS⬜️⬜️⬜️
    31DEFINITION_FOR_MAIN_SCHEMA⬜️⬜️⬜️
    32DEFINITIONS_FOR_MEMBER_SUPERTYPES⬜️⬜️⬜️
    33INLINE_ALL_SCHEMAS⬜️⬜️⬜️
    34INLINE_NULLABLE_SCHEMAS⬜️⬜️⬜️
    35PLAIN_DEFINITION_KEYS⬜️⬜️⬜️
    36ALLOF_CLEANUP_AT_THE_END
    37STRICT_TYPE_INFO⬜️⬜️⬜️
    38NULLABLE_ALWAYS_AS_ANYOF⬜️⬜️⬜️
    +

    Generator – Modules

    +

    Similar to an OptionPreset being a short-cut to including various Options, the concept of Modules is a convenient way of including multiple individual configurations or even advanced configurations (as per the following sections) at once.

    + +

    You can easily group your own set of configurations into a Module if you wish. +However, the main intention behind Modules is that they are an entry-point for separate external dependencies you can "plug-in" as required via SchemaGeneratorConfigBuilder.with(Module), like the few standard Modules documented below.

    + + +

    Generator – Individual Configurations

    +
    +

    E.g. for the given configuration:

    +
    +
    SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09);
    +configBuilder.forField()
    +    .withTitleResolver(field -> field.getName() + " = "
    +            + (field.isFakeContainerItemScope() ? "(fake) " : "(real) ")
    +            + field.getSimpleTypeDescription())
    +    .withDescriptionResolver(field -> "original type = "
    +            + field.getContext().getSimpleTypeDescription(field.getDeclaredType()));
    +JsonNode mySchema = new SchemaGenerator(configBuilder.build())
    +        .generateSchema(MyClass.class);
    +
    +
    +

    and target class:

    +
    +
    class MyClass {
    +    public List<String> texts;
    +}
    +
    +
    +

    The following schema will be generated:

    +
    +
    {
    +  "type": "object",
    +  "properties": {
    +    "texts": {
    +      "type": "array",
    +      "title": "texts = (real) List<String>",
    +      "description": "original type = List<String>",
    +      "items": {
    +        "type": "string",
    +        "title": "texts = (fake) String",
    +        "description": "original type = List<String>"
    +      }
    +    }
    +  }
    +}
    +
    +

    In order to control various attributes being set during the schema generation, you can define for each (supported) one of them individually how a respective value should be resolved. Overall, you usually have the same configuration options either for:

    + +
      +
    • an encountered type in general via SchemaGeneratorConfigBuilder.forTypesInGeneral() or
    • +
    • in the context of a specific field via SchemaGeneratorConfigBuilder.forFields() or
    • +
    • in the context of a specific method's return value via SchemaGeneratorConfigBuilder.forMethods().
    • +
    + + + +

    The jsonschema-generator README contains a list of the supported JSON Schema attributes.
    +The following list of individual configuration options on the SchemaGeneratorConfigBuilder is to a large extent the inverse of that list.

    +

    "$id" Keyword

    configBuilder.forTypesInGeneral()
    +    .withIdResolver(scope -> scope.getType().getErasedType() == MyClass.class ? "main-schema-id" : null);
    +
    +

    withIdResolver() is expecting the "$id" attribute's value to be returned based on a given TypeScope – in case of multiple configurations, the first non-null value will be applied.

    + + +

    "$anchor" Keyword

    configBuilder.forTypesInGeneral()
    +    .withAnchorResolver(scope -> scope.getType().getErasedType() == AnchorClass.class ? "anchor-value" : null);
    +
    +

    withAnchorResolver() is expecting the "$anchor" attribute's value to be returned based on a given TypeScope – in case of multiple configurations, the first non-null value will be applied.

    + + +

    Order of entries in "properties" Keyword

    configBuilder.forTypesInGeneral()
    +    .withPropertySorter(PropertySortUtils.SORT_PROPERTIES_FIELDS_BEFORE_METHODS
    +        .thenComparing((memberOne, memberTwo) ->
    +            // sort fields/methods alphabetically, while ignoring upper/lower case
    +            memberOne.getSchemaPropertyName().toLowerCase()
    +                .compareTo(memberTwo.getSchemaPropertyName().toLowerCase()));
    +
    +

    withPropertySorter() is expecting a Comparator for sorting an object's fields and methods in the produced "properties" – this replaces any previously given sorting algorithm, i.e. only one Comparator can be set – by default, fields are listed before methods with each group in alphabetical order.

    + + +

    Names in global "$defs"/"definitions"

    configBuilder.forTypesInGeneral()
    +    .withDefinitionNamingStrategy(new DefaultSchemaDefinitionNamingStrategy() {
    +        @Override
    +        public String getDefinitionNameForKey(DefinitionKey key, SchemaGenerationContext context) {
    +            return super.getDefinitionNameForKey(key, generationContext).toLowerCase();
    +        }
    +        @Override
    +        public void adjustDuplicateNames(Map<DefinitionKey, String> duplicateNames, SchemaGenerationContext context) {
    +            char suffix = 'a';
    +            duplicateNames.entrySet().forEach(entry -> entry.setValue(entry.getValue() + "-" + suffix++));
    +        }
    +        @Override
    +        public String adjustNullableName(DefinitionKey key, String definitionName, SchemaGenerationContext context) {
    +            return definitionName + "-nullable";
    +        }
    +    });
    +
    +

    withDefinitionNamingStrategy() is expecting a SchemaDefinitionNamingStrategy that defines what keys to assign to subschemas in the "definitions"/"$defs".
    +Optionally, you can override the logic how to adjust them in case of multiple types having the same name and for a subschema's nullable alternative.

    + +

    There is a DefaultSchemaDefinitionNamingStrategy, which is being applied if you don't set a specific naming strategy yourself:

    + +
      +
    • It uses a given type's simple class name (i.e. without package prefix) as the definition name, potentially prepending type arguments in case of it being a parameterized type.
    • +
    • Duplicate names may occur if the same simple class name (with identical type parameters) appears multiple times in your schema, i.e. from different packages. As the definition names need to be unique, those are then prepended with a running number. E.g. java.time.DateTime and your.pkg.DateTime would be represented by DateTime-1 and DateTime-2.
    • +
    • When a given type appears in its nullable and non-nullable form, two separate definitions may be included to reduce duplication. The "normal" named one and the nullable one getting a "-nullable" suffix to its definition name.
    • +
    + + +

    Names of fields/methods in an object's properties

    configBuilder.forFields()
    +    .withPropertyNameOverrideResolver(field -> Optional
    +            .ofNullable(field.getAnnotationConsideringFieldAndGetter(JsonProperty.class))
    +            .map(JsonProperty::value).orElse(null));
    +configBuilder.forMethods()
    +    .withPropertyNameOverrideResolver(method -> method.getName().startsWith("is") && method.getArgumentCount() == 0
    +            ? method.getName().substring(2, method.getName().length() - 2) : null);
    +
    +

    withPropertyNameOverrideResolver() is expecting an alternative name to be returned for a given FieldScope/MethodScope to be used as key in the containing object's "properties" – the first non-null value will be applied.

    + + +

    Omitting/ignoring certain fields/methods

    configBuilder.forFields()
    +    .withIgnoreCheck(field -> field.getName().startsWith("_"));
    +configBuilder.forMethods()
    +    .withIgnoreCheck(method -> !method.isVoid() && method.getType().getErasedType() == Object.class);
    +
    +

    withIgnoreCheck() is expecting the indication to be returned whether a given FieldScope/MethodScope should be excluded from the generated schema. If any check returns true, the field/method will be ignored.

    +

    Decide whether a field's/method's value may be null

    configBuilder.forFields()
    +    .withNullableCheck(field -> field.getAnnotationConsideringFieldAndGetter(Nullable.class) != null);
    +configBuilder.forMethods()
    +    .withNullableCheck(method -> method.getAnnotationConsideringFieldAndGetter(NotNull.class) == null);
    +
    +

    withNullableCheck() is expecting the indication to be returned whether a given FieldScope/MethodScope may return null and should therefore include "null" in the generated schema's "type".

    + +
      +
    • If there is no check or all of them return null, the default will be applied (depending on whether Option.NULLABLE_FIELDS_BY_DEFAULT/Option.NULLABLE_METHOD_RETURN_VALUES_BY_DEFAULT were enabled).
    • +
    • If any check returns true, the field/method will be deemed nullable.
    • +
    • Otherwise, the field/method will be deemed not-nullable.
    • +
    +

    "required" Keyword

    configBuilder.forFields()
    +    .withRequiredCheck(field -> field.getAnnotationConsideringFieldAndGetter(Nullable.class) == null);
    +configBuilder.forMethods()
    +    .withRequiredCheck(method -> method.getAnnotationConsideringFieldAndGetter(NotNull.class) != null);
    +
    +

    withRequiredCheck() is expecting the indication to be returned whether a given FieldScope/MethodScope should be included in the "required" attribute – if any check returns true, the field/method will be deemed "required".

    +

    "dependentRequired" Keyword

    configBuilder.forFields()
    +    .withDependentRequiresResolver(field -> Optional
    +        .ofNullable(field.getAnnotationConsideringFieldAndGetter(IfPresentAlsoRequire.class))
    +        .map(IfPresentAlsoRequire::value)
    +        .map(Arrays::asList)
    +        .orElse(null));
    +configBuilder.forMethods()
    +    .withDependentRequiresResolver(method -> Optional.ofNullable(method.findGetterField())
    +        .map(FieldScope::getSchemaPropertyName)
    +        .map(Collections::singletonList)
    +        .orElse(null));
    +
    +

    withDependentRequiresResolver() is expecting the names of other properties to be returned, which should be deemed "required", if the property represented by the given field/method is present. +The results of all registered resolvers are being combined.

    +

    "readOnly" Keyword

    configBuilder.forFields()
    +    .withReadOnlyCheck(field -> field.getAnnotationConsideringFieldAndGetter(ReadOnly.class) != null);
    +configBuilder.forMethods()
    +    .withReadOnlyCheck(method -> method.getAnnotationConsideringFieldAndGetter(ReadOnly.class) != null);
    +
    +

    withReadOnlyCheck() is expecting the indication to be returned whether a given FieldScope/MethodScope should be included in the "readOnly" attribute – if any check returns true, the field/method will be deemed "readOnly".

    +

    "writeOnly" Keyword

    configBuilder.forFields()
    +    .withWriteOnlyCheck(field -> field.getAnnotationConsideringFieldAndGetter(WriteOnly.class) != null);
    +configBuilder.forMethods()
    +    .withWriteOnlyCheck(method -> method.getAnnotationConsideringFieldAndGetter(WriteOnly.class) != null);
    +
    +

    withWriteOnlyCheck() is expecting the indication to be returned whether a given FieldScope/MethodScope should be included in the "writeOnly" attribute – if any check returns true, the field/method will be deemed "writeOnly".

    +

    "title" Keyword

    configBuilder.forTypesInGeneral()
    +    .withTitleResolver(scope -> scope.getType().getErasedType() == YourClass.class ? "main schema title" : null);
    +configBuilder.forFields()
    +    .withTitleResolver(field -> field.getType().getErasedType() == String.class ? "text field" : null);
    +configBuilder.forMethods()
    +    .withTitleResolver(method -> method.getName().startsWith("get") ? "getter" : null);
    +
    +

    withTitleResolver() is expecting the "title" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "description" Keyword

    configBuilder.forTypesInGeneral()
    +    .withDescriptionResolver(scope -> scope.getType().getErasedType() == YourClass.class ? "main schema description" : null);
    +configBuilder.forFields()
    +    .withDescriptionResolver(field -> field.getType().getErasedType() == String.class ? "text field" : null);
    +configBuilder.forMethods()
    +    .withDescriptionResolver(method -> method.getName().startsWith("get") ? "getter" : null);
    +
    +

    withDescriptionResolver() is expecting the "description" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "default" Keyword

    configBuilder.forTypesInGeneral()
    +    .withDefaultResolver(scope -> scope.getType().getErasedType() == boolean.class ? Boolean.FALSE : null);
    +configBuilder.forFields()
    +    .withDefaultResolver(field -> field.getType().getErasedType() == String.class ? "" : null);
    +configBuilder.forMethods()
    +    .withDefaultResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetter(Default.class))
    +            .map(Default::value).orElse(null));
    +
    +

    withDefaultResolver() is expecting the "default" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied, which will be serialised through the ObjectMapper instance provided in the SchemaGeneratorConfigBuilder's constructor.

    +

    "const"/"enum" Keyword

    configBuilder.forTypesInGeneral()
    +    .withEnumResolver(scope -> scope.getType().getErasedType().isEnum()
    +            ? Stream.of(scope.getType().getErasedType().getEnumConstants())
    +                    .map(v -> ((Enum) v).name()).collect(Collectors.toList())
    +            : null);
    +configBuilder.forFields()
    +    .withEnumResolver(field -> Optional
    +            .ofNullable(field.getAnnotationConsideringFieldAndGetter(AllowedValues.class))
    +            .map(AllowedValues::valueList).orElse(null));
    +configBuilder.forMethods()
    +    .withEnumResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetter(SupportedValues.class))
    +            .map(SupportedValues::values).map(Arrays::asList).orElse(null));
    +
    +

    withEnumResolver() is expecting the "const"/"enum" attribute's value(s) to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied, which will be serialised through the ObjectMapper instance provided in the SchemaGeneratorConfigBuilder's constructor.

    +

    "additionalProperties" Keyword

    +
    +

    Option 1: derive plain type from given scope

    +
    + +

    One version of the withAdditionalPropertiesResolver() is expecting the "additionalProperties" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +
    configBuilder.forTypesInGeneral()
    +    .withAdditionalPropertiesResolver(scope -> Object.class);
    +configBuilder.forFields()
    +    .withAdditionalPropertiesResolver(field -> field.getType().getErasedType() == Object.class
    +            ? null : Void.class);
    +configBuilder.forMethods()
    +    .withAdditionalPropertiesResolver(method -> method.getType().getErasedType() == Map.class
    +            ? method.getTypeParameterFor(Map.class, 1) : Void.class);
    +
    +
      +
    • If null is being returned, the next registered AdditionalPropertiesResolver will be checked. If all return null, the attribute will be omitted.
    • +
    • If Object.class is being returned, the "additionalProperties" attribute will be omitted.
    • +
    • if Void.class is being returned, the "additionalProperties" will be set to false.
    • +
    • If any other type is being returned (e.g. other Class or a ResolvedType) a corresponding schema will be included in "additionalProperties".
    • +
    + +
    +

    Option 2: specify explicit subschema

    +
    + +

    Another version of the withAdditionalPropertiesResolver() is expecting the "additionalProperties" attribute's value to be provided directly as a JsonNode (e.g., ObjectNode) representing the desired subschema. +In this case, both the TypeScope/FieldScope/MethodScope and the overall generation context are being provided as input parameters.

    +
    configBuilder.forTypesInGeneral()
    +    .withAdditionalPropertiesResolver((scope, context) -> BooleanNode.TRUE);
    +configBuilder.forFields()
    +    .withAdditionalPropertiesResolver((field, context) -> field.getType().getErasedType() == Object.class
    +            ? null : BooleanNode.FALSE);
    +configBuilder.forMethods()
    +    .withAdditionalPropertiesResolver((method, context) -> {
    +        if (!method.getType().isInstanceOf(Map.class)) {
    +            return null;
    +        }
    +        ResolvedType valueType = method.getTypeParameterFor(Map.class, 1);
    +        if (valueType == null || valueType.getErasedType() == Object.class) {
    +            return null;
    +        }
    +        return context.createStandardDefinitionReference(method.asFakeContainerItemScope(Map.class, 1), null);
    +    });
    +
    +
      +
    • If null is being returned, the next registered AdditionalPropertiesResolver will be checked. If all return null, the attribute will be omitted.
    • +
    • If BooleanNode.TRUE is being returned, the "additionalProperties" attribute will be omitted.
    • +
    • if BooleanNode.FALSE is being returned, the "additionalProperties" will be set to false.
    • +
    • If any other subschema is being returned, that will be included as "additionalProperties" attribute directly.
    • +
    + +

    This usage of the FieldScope/MethodScope potentially via asFakeContainerItemScope() has the advantage of allowing the consideration of annotations on generic parameters, such as the one on Map<String, @Min(10) Integer> when that is the declared type of a field/method. +

    +

    "patternProperties" Keyword

    +
    +

    Option 1: derive plain types from given scope

    +
    + +

    One version of the withPatternPropertiesResolver() is expecting a Map of regular expressions to their corresponding allowed types to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +
    configBuilder.forTypesInGeneral()
    +    .withPatternPropertiesResolver(scope -> scope.getType().isInstanceOf(Map.class)
    +            ? Collections.singletonMap("^[a-zA-Z]+$", scope.getTypeParameterFor(Map.class, 1)) : null);
    +configBuilder.forFields()
    +    .withPatternPropertiesResolver(field -> field.getType().isInstanceOf(TypedMap.class)
    +            ? Collections.singletonMap("_int$", int.class) : null);
    +configBuilder.forMethods()
    +    .withPatternPropertiesResolver(method -> method.getType().isInstanceOf(StringMap.class)
    +            ? Collections.singletonMap("^txt_", String.class) : null);
    +
    +

    Each regular expression will be included as key in the "patternProperties" attribute with a schema representing the mapped type as the corresponding value.

    + +
    +

    Option 2: specify explicit subschema

    +
    + +

    Another version of the withPatternPropertiesResolver() is expecting a Map with each value being a JsonNode (e.g., ObjectNode) representing the respective desired subschema. +In this case, both the TypeScope/FieldScope/MethodScope and the overall generation context are being provided as input parameters.

    + +
    +

    The generation of the subschema could look similar to the example given for the "additionalProperties" attribute above.

    +
    + +

    The usage of the FieldScope/MethodScope potentially via asFakeContainerItemScope() has the advantage of allowing the consideration of annotations on generic parameters, such as the one on Map<String, @Min(10) Integer> when that is the declared type of a field/method.

    +

    "minLength" Keyword

    configBuilder.forTypesInGeneral()
    +    .withStringMinLengthResolver(scope -> scope.getType().getErasedType() == UUID.class ? 36 : null);
    +configBuilder.forFields()
    +    .withStringMinLengthResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(NotEmpty.class) == null ? null : 1);
    +configBuilder.forMethods()
    +    .withStringMinLengthResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Size.class))
    +            .map(Size::min).orElse(null));
    +
    +

    withStringMinLengthResolver() is expecting the "minLength" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "maxLength" Keyword

    configBuilder.forTypesInGeneral()
    +    .withStringMaxLengthResolver(scope -> scope.getType().getErasedType() == UUID.class ? 36 : null);
    +configBuilder.forFields()
    +    .withStringMaxLengthResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(DbKey.class) == null ? null : 450);
    +configBuilder.forMethods()
    +    .withStringMaxLengthResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Size.class))
    +            .map(Size::max).orElse(null));
    +
    +

    withStringMaxLengthResolver() is expecting the "maxLength" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "format" Keyword

    configBuilder.forTypesInGeneral()
    +    .withStringFormatResolver(scope -> scope.getType().getErasedType() == UUID.class ? "uuid" : null);
    +configBuilder.forFields()
    +    .withStringFormatResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(Email.class) == null ? null : "email");
    +configBuilder.forMethods()
    +    .withStringFormatResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Schema.class))
    +            .map(Schema::format).orElse(null));
    +
    +

    withStringFormatResolver() is expecting the "format" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "pattern" Keyword

    configBuilder.forTypesInGeneral()
    +    .withStringPatternResolver(scope -> scope.getType().getErasedType() == UUID.class
    +            ? "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[89aAbB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" : null);
    +configBuilder.forFields()
    +    .withStringPatternResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(Email.class) == null ? null : "^.+@.+\\..+$");
    +configBuilder.forMethods()
    +    .withStringPatternResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Pattern.class))
    +            .map(Pattern::value).orElse(null));
    +
    +

    withStringPatternResolver() is expecting the "pattern" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "minimum" Keyword

    configBuilder.forTypesInGeneral()
    +    .withNumberInclusiveMinimumResolver(scope -> scope.getType().getErasedType() == PositiveInt.class
    +            ? BigDecimal.ONE : null);
    +configBuilder.forFields()
    +    .withNumberInclusiveMinimumResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(NonNegative.class) == null ? null : BigDecimal.ZERO);
    +configBuilder.forMethods()
    +    .withNumberInclusiveMinimumResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Minimum.class))
    +            .filter(a -> !a.exclusive()).map(Minimum::value).orElse(null));
    +
    +

    withNumberInclusiveMinimumResolver() is expecting the "minimum" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "exclusiveMinimum" Keyword

    configBuilder.forTypesInGeneral()
    +    .withNumberExclusiveMinimumResolver(scope -> scope.getType().getErasedType() == PositiveDecimal.class
    +            ? BigDecimal.ZERO : null);
    +configBuilder.forFields()
    +    .withNumberExclusiveMinimumResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(Positive.class) == null ? null : BigDecimal.ZERO);
    +configBuilder.forMethods()
    +    .withNumberExclusiveMinimumResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Minimum.class))
    +            .filter(Minimum::exclusive).map(Minimum::value).orElse(null));
    +
    +

    withNumberExclusiveMinimumResolver() is expecting the "exclusiveMinimum" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "maximum" Keyword

    configBuilder.forTypesInGeneral()
    +    .withNumberInclusiveMaximumResolver(scope -> scope.getType().getErasedType() == int.class
    +            ? new BigDecimal(Integer.MAX_VALUE) : null);
    +configBuilder.forFields()
    +    .withNumberInclusiveMaximumResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(NonPositive.class) == null ? null : BigDecimal.ZERO);
    +configBuilder.forMethods()
    +    .withNumberInclusiveMaximumResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Maximum.class))
    +            .filter(a -> !a.exclusive()).map(Maximum::value).orElse(null));
    +
    +

    withNumberInclusiveMaximumResolver() is expecting the "maximum" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "exclusiveMaximum" Keyword

    configBuilder.forTypesInGeneral()
    +    .withNumberExclusiveMaximumResolver(scope -> scope.getType().getErasedType() == NegativeInt.class
    +            ? BigDecimal.ZERO : null);
    +configBuilder.forFields()
    +    .withNumberExclusiveMaximumResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(Negative.class) == null ? null : BigDecimal.ZERO);
    +configBuilder.forMethods()
    +    .withNumberExclusiveMaximumResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Maximum.class))
    +            .filter(Maximum::exclusive).map(Maximum::value).orElse(null));
    +
    +

    withNumberExclusiveMaximumResolver() is expecting the "exclusiveMaximum" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "multipleOf" Keyword

    configBuilder.forTypesInGeneral()
    +    .withNumberMultipleOfResolver(scope -> scope.getType().getErasedType() == int.class
    +            ? BigDecimal.ONE : null);
    +configBuilder.forFields()
    +    .withNumberMultipleOfResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(Currency.class) == null ? null : new BigDecimal("0.01"));
    +configBuilder.forMethods()
    +    .withNumberMultipleOfResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(NumericConstraint.class))
    +            .map(NumericConstraint::multipleOf).orElse(null));
    +
    +

    withNumberMultipleOfResolver() is expecting the "multipleOf" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "minItems" Keyword

    configBuilder.forTypesInGeneral()
    +    .withArrayMinItemsResolver(scope -> scope.getType().isInstanceOf(MandatoryList.class) ? 1 : null);
    +configBuilder.forFields()
    +    .withArrayMinItemsResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(NotEmpty.class) == null ? null : 1);
    +configBuilder.forMethods()
    +    .withArrayMinItemsResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Size.class))
    +            .map(Size::min).orElse(null));
    +
    +

    withArrayMinItemsResolver() is expecting the "minItems" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "maxItems" Keyword

    configBuilder.forTypesInGeneral()
    +    .withArrayMaxItemsResolver(scope -> scope.getType().isInstanceOf(Triple.class) ? 3 : null);
    +configBuilder.forFields()
    +    .withArrayMaxItemsResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(NoMoreThanADozen.class) == null ? null : 12);
    +configBuilder.forMethods()
    +    .withArrayMaxItemsResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(Size.class))
    +            .map(Size::max).orElse(null));
    +
    +

    withArrayMaxItemsResolver() is expecting the "maxItems" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    "uniqueItems" Keyword

    configBuilder.forTypesInGeneral()
    +    .withArrayUniqueItemsResolver(scope -> scope.getType().isInstanceOf(Set.class) ? true : null);
    +configBuilder.forFields()
    +    .withArrayUniqueItemsResolver(field -> field
    +            .getAnnotationConsideringFieldAndGetterIfSupported(Unique.class) == null ? null : true);
    +configBuilder.forMethods()
    +    .withArrayUniqueItemsResolver(method -> Optional
    +            .ofNullable(method.getAnnotationConsideringFieldAndGetterIfSupported(ListConstraints.class))
    +            .map(ListConstraints::distinct).orElse(null));
    +
    +

    withArrayUniqueItemsResolver() is expecting the "uniqueItems" attribute's value to be returned based on a given TypeScope/FieldScope/MethodScope – the first non-null value will be applied.

    +

    Generator – Advanced Configurations

    +

    When all of the above configuration options are insufficient to achieve your requirements, there are some more advanced configurations you can resort to.

    +

    Instance Attribute Overrides

    configBuilder.forFields()
    +    .withInstanceAttributeOverride((node, field, context) -> node
    +            .put("$comment", "Field name in code: " + field.getDeclaredName()));
    +configBuilder.forMethods()
    +    .withInstanceAttributeOverride((node, method, context) -> node
    +            .put("readOnly", true));
    +
    +

    If you want to set an attribute that is missing in the supported Individual Configurations for fields/methods or just want to have the last say in what combination of attribute values is being set for a field/method, you can use the following configurations:

    + +
      +
    • SchemaGeneratorConfigBuilder.forFields().withInstanceAttributeOverride()
    • +
    • SchemaGeneratorConfigBuilder.forMethods().withInstanceAttributeOverride()
    • +
    + +

    All defined overrides will be applied in the order of having been added to the SchemaGeneratorConfigBuilder. Each receiving the then-current set of attributes on an ObjectNode which can be freely manipulated.

    +

    Type Attribute Overrides

    configBuilder.forTypesInGeneral()
    +    .withTypeAttributeOverride((node, scope, context) -> node
    +            .put("$comment", "Java type: " + scope.getType().getErasedType().getName()));
    +
    +

    Similarly to (but not quite the same as) the Instance Attribute Overrides for fields/methods you can add missing attributes or manipulate collected ones on a per-type level through the following configuration:

    + +
      +
    • SchemaGeneratorConfigBuilder.forTypesInGeneral().withTypeAttributeOverride()
    • +
    + +

    All defined overrides will be applied in the order of having been added to the SchemaGeneratorConfigBuilder. +Each receiving the then-current type definition including the collected set of attributes on an ObjectNode which can be freely manipulated.

    +

    Target Type Overrides

    +
    +

    E.g. for the value field in the following class you may know that the returned value is either a String or a Number but there is no common supertype but Object that can be declared:

    +
    +
    class ExampleForTargetTypeOverrides {
    +    @ValidOneOfTypes({String.class, Number.class})
    +    private Object value;
    +
    +    public void setValue(String textValue) {
    +        this.value = textValue;
    +    }
    +    public void setValue(Number numericValue) {
    +        this.value = numericValue;
    +    }
    +}
    +
    +
    +

    This could be solved by the following configuration:

    +
    +
    configBuilder.forFields()
    +    .withTargetTypeOverridesResolver(field -> Optional
    +            .ofNullable(field.getAnnotationConsideringFieldAndGetterIfSupported(ValidOneOfTypes.class))
    +            .map(ValidOneOfTypes::value).map(Stream::of)
    +            .map(stream -> stream.map(specificSubtype -> field.getContext().resolve(specificSubtype)))
    +            .map(stream -> stream.collect(Collectors.toList()))
    +            .orElse(null));
    +
    +
    +

    The generated schema would look like this then:

    +
    +
    {
    +    "type": "object",
    +    "properties": {
    +        "value": {
    +            "anyOf": [
    +                { "type": "string" },
    +                { "type": "number" }
    +            ]
    +        }
    +    }
    +}
    +
    +

    Java does not support multiple type alternatives to be declared. This means you may have to declare a rather generic type on a field or as a method's return value even though there is only a finite list of types that you actually expect to be returned. +To improve the generated schema by listing the actual alternatives via "anyOf", you can make use of the following configurations:

    + +
      +
    • SchemaGeneratorConfigBuilder.forFields().withTargetTypeOverridesResolver()
    • +
    • SchemaGeneratorConfigBuilder.forMethods().withTargetTypeOverridesResolver()
    • +
    +

    Subtype Resolvers

    +
    +

    E.g. to replace every occurrence of the Animal interface with the Cat and Dog implementations:

    +
    +
    configBuilder.forTypesInGeneral()
    +    .withSubtypeResolver((declaredType, generationContext) -> {
    +        if (declaredType.getErasedType() == Animal.class) {
    +            TypeContext typeContext = generationContext.getTypeContext();
    +            return Arrays.asList(
    +                    typeContext.resolveSubtype(declaredType, Cat.class),
    +                    typeContext.resolveSubtype(declaredType, Dog.class)
    +            );
    +        }
    +        return null;
    +    });
    +
    +

    When a declared type is not too broad as in the example for Target Type Overrides above, but rather an appropriate supertype or interface. You may also want to list the alternative implementations via "anyOf" wherever you encounter an abstract class or interface. +In order to reflect Java's polymorphism, you can make use of the following configuration:

    + +
      +
    • SchemaGeneratorConfigBuilder.forTypesInGeneral().withSubtypeResolver()
    • +
    + +

    This can of course be more generalised by employing your reflections library of choice for scanning your classpath for all implementations of an encountered type.

    +

    Custom Type Definitions

    +
    +

    E.g. treat Collections as objects and not as "type": "array" (which is the default):

    +
    +
    configBuilder.forTypesInGeneral()
    +    .withCustomDefinitionProvider((javaType, context) -> {
    +        if (!javaType.isInstanceOf(Collection.class)) {
    +            return null;
    +        }
    +        ResolvedType generic = context.getTypeContext().getContainerItemType(javaType);
    +        SchemaGeneratorConfig config = context.getGeneratorConfig();
    +        return new CustomDefinition(context.getGeneratorConfig().createObjectNode()
    +                .put(config.getKeyword(SchemaKeyword.TAG_TYPE),
    +                        config.getKeyword(SchemaKeyword.TAG_TYPE_OBJECT))
    +                .set(config.getKeyword(SchemaKeyword.TAG_PROPERTIES),
    +                        config.createObjectNode().set("stream().findFirst().orElse(null)",
    +                                context.makeNullable(context.createDefinitionReference(generic)))));
    +    });
    +
    +

    When all the generic configurations are not enough to achieve your specific requirements, you can still directly define parts of the schema yourself through the following configuration:

    + +
      +
    • SchemaGeneratorConfigBuilder.forTypesInGeneral().withCustomDefinitionProvider()
    • +
    + +
    +

    (1) When including an unchanged schema of a different type, use createDefinitionReference():

    +
    +
    configBuilder.forTypesInGeneral()
    +    .withCustomDefinitionProvider((javaType, context) ->
    +        javaType.isInstanceOf(UUID.class)
    +            ? new CustomDefinition(context.createDefinitionReference(
    +                    context.getTypeContext().resolve(String.class)))
    +            : null);
    +
    +
    +

    (2) When including an unchanged schema of the same type, use createStandardDefinitionReference():

    +
    +
    CustomDefinitionProviderV2 thisProvider = (javaType, context) -> 
    +    javaType.isInstanceOf(Collection.class)
    +        ? new CustomDefinition(
    +            context.createStandardDefinitionReference(javaType, thisProvider),
    +            DefinitionType.STANDARD, AttributeInclusion.NO)
    +        : null;
    +configBuilder.forTypesInGeneral()
    +    .withCustomDefinitionProvider(thisProvider);
    +
    +
    +

    (3) When adjusting a schema of a different type, use createDefinition():

    +
    +
    configBuilder.forTypesInGeneral()
    +    .withCustomDefinitionProvider((javaType, context) ->
    +        javaType.isInstanceOf(UUID.class)
    +            ? new CustomDefinition(context.createDefinition(
    +                    context.getTypeContext().resolve(String.class))
    +                        .put("format", "uuid"))
    +            : null);
    +
    +
    +

    (4) When adjusting a schema of the same type, use createStandardDefinition():

    +
    +
    CustomDefinitionProviderV2 thisProvider = (javaType, context) -> 
    +    javaType.isInstanceOf(Collection.class)
    +        ? new CustomDefinition(
    +                context.createStandardDefinition(javaType, thisProvider)
    +                    .put("$comment", "collection without other attributes"),
    +                DefinitionType.STANDARD, AttributeInclusion.NO)
    +        : null;
    +configBuilder.forTypesInGeneral()
    +    .withCustomDefinitionProvider(thisProvider);
    +
    + + +
      +
    1. SchemaGenerationContext.createDefinitionReference() creates a temporarily empty node which will be populated later with either a $ref or the appropriate inline schema, i.e. in order to not produce an inline definition – thereby allowing you to avoid endless loops in case of circular references.
    2. +
    3. SchemaGenerationContext.createStandardDefinitionReference() to be used instead of the above when targeting the same type, to skip the current definition provider (and all previous ones) and thereby avoid endless loops.
    4. +
    5. SchemaGenerationContext.createDefinition() creates an inline definition of the given scope, allowing you to apply changes on top (similar to attribute overrides); thereby avoiding the need to manually create everything from scratch.
    6. +
    7. SchemaGenerationContext.createStandardDefinition() to be used instead of the above when targeting the same type, to skip the current definition provider (and all previous ones) and thereby avoid endless loops.
    8. +
    + +

    Other useful methods available in the context of a custom definition provider are:

    + +
      +
    • SchemaGenerationContext.getGeneratorConfig().getObjectMapper().readTree() allowing you to parse a string into a json (schema), in case you prefer to statically provide (parts of) the custom definitions.
    • +
    • SchemaGenerationContext.getTypeContext().resolve() allowing you to produce ResolvedType instances which are expected by various other methods.
    • +
    + + +

    Custom Property Definitions

    // read a static schema string from an annotation
    +CustomPropertyDefinitionProvider provider = (member, context) -> Optional
    +        .ofNullable(member.getAnnotationConsideringFieldAndGetter(Subschema.class))
    +        .map(Subschema::value)
    +        .map(rawSchema -> {
    +            try {
    +                return context.getGeneratorConfig().getObjectMapper().readTree(rawSchema);
    +            } catch (Exception ex) {
    +                return null;
    +            }
    +        })
    +        .map(CustomPropertyDefinition::new)
    +        .orElse(null);
    +// if you don't rely on specific field/method functionality,
    +// you can reuse the same provider for both of them
    +configBuilder.forFields().withCustomDefinitionProvider(provider);
    +configBuilder.forMethods().withCustomDefinitionProvider(provider);
    +
    +

    When not even the Custom Type Definitions are flexible enough for you and you need to consider the specific field/method context in which a type is being encountered, there is one last path you can take:

    + +
      +
    • SchemaGeneratorConfigBuilder.forFields().withCustomDefinitionProvider()
    • +
    • SchemaGeneratorConfigBuilder.forMethods().withCustomDefinitionProvider()
    • +
    + + + + +

    Order of Object Properties

    // sort by custom @JsonPropertyIndex(3) annotation
    +configBuilder.forTypesInGeneral()
    +        .withPropertySorter(Comparator.comparing(member -> Optional.ofNullable(member.getAnnotation(JsonPropertyIndex.class))
    +                .map(JsonPropertyIndex::value)
    +                .orElse(0)));
    +
    // preserve property order in byte code (determined by compiler)
    +configBuilder.forTypesInGeneral()
    +        .withPropertySorter((first, second) -> 0);
    +
    +

    You may want to control the order in which an object's properties are being listed, e.g., when using the JSON schema as basis for an auto-generated form in some user interface.
    +By default, fields are being included before methods -- with each sublist being sorted alphabetically.

    + +

    You can define your own Comparator<MemberScope<?, ?>>, e.g., considering an annotation specifying the desired order or disable the sorting by always returning zero (0).
    +With disabled property sorting, your compiler decides the order of the properties in your generated JSON schema. Depending on the compiler, this may correspond to the declaration order in your source file but is not guaranteed.

    +

    Jackson Module

    +

    The victools:jsonschema-module-jackson provides a number of standard configurations for deriving JSON Schema attributes from jackson annotations as well as looking up appropriate (annotated) subtypes.

    +
    import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
    +import com.github.victools.jsonschema.generator.SchemaVersion;
    +import com.github.victools.jsonschema.module.jackson.JacksonModule;
    +import com.github.victools.jsonschema.module.jackson.JacksonOption;
    +
    +
    +JacksonModule module = new JacksonModule(
    +        JacksonOption.FLATTENED_ENUMS_FROM_JSONVALUE
    +);
    +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09)
    +    .with(module);
    +
    +
      +
    1. Set a field/method's "description" as per @JsonPropertyDescription
    2. +
    3. Set a type's "description" as per @JsonClassDescription.
    4. +
    5. Override a field's/method's property name as per @JsonProperty annotations.
    6. +
    7. Ignore fields/methods that are marked with a @JsonBackReference annotation.
    8. +
    9. Ignore fields (and their associated getter methods) that are deemed to be ignored according to various other jackson-annotations (e.g. @JsonIgnore, @JsonIgnoreType, @JsonIgnoreProperties) or are otherwise supposed to be excluded.
    10. +
    11. Optionally: set a field/method as "required" as per @JsonProperty annotations, if the JacksonOption.RESPECT_JSONPROPERTY_REQUIRED was provided (i.e. this is an "opt-in").
    12. +
    13. Optionally: treat enum types as plain strings as per the @JsonValue annotated method, if there is one and the JacksonOption.FLATTENED_ENUMS_FROM_JSONVALUE was provided (i.e. this is an "opt-in").
    14. +
    15. Optionally: treat enum types as plain strings, as per each enum constant's @JsonProperty annotation, if all values of an enum have such annotations and the JacksonOption.FLATTENED_ENUMS_FROM_JSONPROPERTY was provided (i.e. this is an "opt-in").
    16. +
    17. Optionally: sort an object's properties according to its @JsonPropertyOrder annotation, if the JacksonOption.RESPECT_JSONPROPERTY_ORDER was provided (i.e. this is an "opt-in").
    18. +
    19. Subtype resolution according to @JsonSubTypes on a supertype in general or directly on specific fields/methods as an override of the per-type behavior unless JacksonOption.SKIP_SUBTYPE_LOOKUP was provided (i.e. this is an "opt-out").
    20. +
    21. Apply structural changes for subtypes according to @JsonTypeInfo on a supertype in general or directly on specific fields/methods as an override of the per-type behavior unless JacksonOption.IGNORE_TYPE_INFO_TRANSFORM was provided (i.e. this is an "opt-out"). + +
        +
      • Considering @JsonTypeInfo.include with values As.PROPERTY, As.EXISTING_PROPERTY, As.WRAPPER_ARRAY, As.WRAPPER_OBJECT
      • +
      • Considering @JsonTypeInfo.use with values Id.CLASS, Id.NAME
      • +
    22. +
    23. Consider @JsonProperty.access for marking a field/method as readOnly or writeOnly
    24. +
    25. Optionally: ignore all methods but those with a @JsonProperty annotation, if the JacksonOption.INCLUDE_ONLY_JSONPROPERTY_ANNOTATED_METHODS was provided (i.e. this is an "opt-in").
    26. +
    27. Optionally: respect @JsonIdentityReference(alwaysAsId=true) annotation if there is a corresponding @JsonIdentityInfo annotation on the type and the JacksonOption.JSONIDENTITY_REFERENCE_ALWAYS_AS_ID as provided (i.e., this is an "opt-in")
    28. +
    29. Elevate nested properties to the parent type where members are annotated with @JsonUnwrapped.
    30. +
    31. Support @JacksonAnnotationsInside annotated combo annotations
    32. +
    + +

    Schema attributes derived from annotations on getter methods are also applied to their associated fields.

    + +

    To use it, just pass a module instance into SchemaGeneratorConfigBuilder.with(Module), optionally providing JacksonOption values in the module's constructor.

    + +
    + +

    For a description of the available JacksonOption values and their meaning (apart from their mentionings in above enumeration), please refer to the JacksonOption class or its JavaDoc.

    +

    Jakarta Validation Module

    +

    The victools:jsonschema-module-jakarta-validation provides a number of standard configurations for deriving JSON Schema attributes from jakarta.validation.constraints annotations.

    +
    import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
    +import com.github.victools.jsonschema.generator.SchemaVersion;
    +import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationModule;
    +import com.github.victools.jsonschema.module.jakarta.validation.JakartaValidationOption;
    +
    +
    +JakartaValidationModule module = new JakartaValidationModule(JakartaValidationOption.PREFER_IDN_EMAIL_FORMAT)
    +    .forValidationGroups(YourGroupFlag.class);
    +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09)
    +    .with(module);
    +
    +
      +
    1. Determine whether a member is not nullable, base assumption being that all fields and method return values are nullable if not annotated. Based on @NotNull/@Null/@NotEmpty/@NotBlank.
    2. +
    3. Populate list of "required" fields/methods for objects if JakartaValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED/JakartaValidationOption.NOT_NULLABLE_METHOD_IS_REQUIRED is being provided respectively (i.e. this is an "opt-in").
    4. +
    5. Populate "minItems" and "maxItems" for containers (i.e. arrays and collections). Based on @Size/@NotEmpty.
    6. +
    7. Populate "minProperties" and "maxProperties" for map types. Based on @Size/@NotEmpty.
    8. +
    9. Populate "minLength" and "maxLength" for strings. Based on @Size/@NotEmpty/@NotBlank.
    10. +
    11. Populate "format" for strings. Based on @Email, can be "email" or "idn-email" depending on whether JakartaValidationOption.PREFER_IDN_EMAIL_FORMAT is being provided.
    12. +
    13. Populate "pattern" for strings. Based on @Pattern/@Email, if JakartaValidationOption.INCLUDE_PATTERN_EXPRESSIONS is being provided (i.e. this is an "opt-in").
    14. +
    15. Populate "minimum"/"exclusiveMinimum" for numbers. Based on @Min/@DecimalMin/@Positive/@PositiveOrZero.
    16. +
    17. Populate "maximum"/"exclusiveMaximum" for numbers. Based on @Max/@DecimalMax/@Negative/@NegativeOrZero.
    18. +
    19. Populate "enum"/"const" for booleans. Based on @AssertTrue/@AssertFalse.
    20. +
    + +

    Schema attributes derived from validation annotations on fields are also applied to their respective getter methods.
    +Schema attributes derived from validation annotations on getter methods are also applied to their associated fields.

    + +

    To use it, just pass a module instance into SchemaGeneratorConfigBuilder.with(Module), optionally providing JakartaValidationOption values in the module's constructor and/or specifying validation groups to filter by via .forValidationGroups().

    +
    module.forValidationGroups(JsonSchemaValidation.class);
    +
    +

    The jakarta.validation.constraints annotations cater for a groups parameter to be added, to allow different sets of validations to be applied under different circumstances. +Via .forValidationGroups() you're able to indicate which groups should be considered during the schema generation. +Without specifying particular groups via .forValidationGroups(), no filtering will be applied – i.e. all supported jakarta.validation.constraints annotations will be considered regardless of their respective groups.

    +

    Javax Validation Module

    +

    The victools:jsonschema-module-javax-validation provides a number of standard configurations for deriving JSON Schema attributes from javax.validation annotations.

    +
    import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
    +import com.github.victools.jsonschema.generator.SchemaVersion;
    +import com.github.victools.jsonschema.module.javax.validation.JavaxValidationModule;
    +import com.github.victools.jsonschema.module.javax.validation.JavaxValidationOption;
    +
    +
    +JavaxValidationModule module = new JavaxValidationModule(JavaxValidationOption.PREFER_IDN_EMAIL_FORMAT)
    +    .forValidationGroups(YourGroupFlag.class);
    +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09)
    +    .with(module);
    +
    +
      +
    1. Determine whether a member is not nullable, base assumption being that all fields and method return values are nullable if not annotated. Based on @NotNull/@Null/@NotEmpty/@NotBlank.
    2. +
    3. Populate list of "required" fields/methods for objects if JavaxValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED/JavaxValidationOption.NOT_NULLABLE_METHOD_IS_REQUIRED is being provided respectively (i.e. this is an "opt-in").
    4. +
    5. Populate "minItems" and "maxItems" for containers (i.e. arrays and collections). Based on @Size/@NotEmpty.
    6. +
    7. Populate "minLength" and "maxLength" for strings. Based on @Size/@NotEmpty/@NotBlank.
    8. +
    9. Populate "format" for strings. Based on @Email, can be "email" or "idn-email" depending on whether JavaxValidationOption.PREFER_IDN_EMAIL_FORMAT is being provided.
    10. +
    11. Populate "pattern" for strings. Based on @Pattern/@Email, if JavaxValidationOption.INCLUDE_PATTERN_EXPRESSIONS is being provided (i.e. this is an "opt-in").
    12. +
    13. Populate "minimum"/"exclusiveMinimum" for numbers. Based on @Min/@DecimalMin/@Positive/@PositiveOrZero.
    14. +
    15. Populate "maximum"/"exclusiveMaximum" for numbers. Based on @Max/@DecimalMax/@Negative/@NegativeOrZero.
    16. +
    + +

    Schema attributes derived from validation annotations on fields are also applied to their respective getter methods.
    +Schema attributes derived from validation annotations on getter methods are also applied to their associated fields.

    + +

    To use it, just pass a module instance into SchemaGeneratorConfigBuilder.with(Module), optionally providing JavaxValidationOption values in the module's constructor and/or specifying validation groups to filter by via .forValidationGroups().

    +
    module.forValidationGroups(JsonSchemaValidation.class);
    +
    +

    The javax.validation annotations cater for a groups parameter to be added, to allow different sets of validations to be applied under different circumstances. +Via .forValidationGroups() you're able to indicate which groups should be considered during the schema generation. +Without specifying particular groups via .forValidationGroups(), no filtering will be applied – i.e. all supported javax.validation annotations will be considered regardless of their respective groups.

    +

    Swagger 1.5 Module

    +

    The victools:jsonschema-module-swagger-1.5 provides a number of standard configurations for deriving JSON Schema attributes from swagger (1.5.x) annotations.

    +
    import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
    +import com.github.victools.jsonschema.generator.SchemaVersion;
    +import com.github.victools.jsonschema.module.swagger15.SwaggerModule;
    +import com.github.victools.jsonschema.module.swagger15.SwaggerOption;
    +
    +
    +SwaggerModule module = new SwaggerModule(
    +        SwaggerOption.ENABLE_PROPERTY_NAME_OVERRIDES,
    +        SwaggerOption.IGNORING_HIDDEN_PROPERTIES
    +);
    +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09)
    +    .with(module);
    +
    +
      +
    1. Set a field/method's "description" as per @ApiModelProperty(value = ...)
    2. +
    3. Set a type's "title" as per @ApiModel(value = ...) unless SwaggerOption.NO_APIMODEL_TITLE was provided (i.e. this is an "opt-out")
    4. +
    5. Set a type's "description" as per @ApiModel(description = ...) unless SwaggerOption.NO_APIMODEL_DESCRIPTION was provided (i.e. this is an "opt-out")
    6. +
    7. Ignore a field/method if @ApiModelProperty(hidden = true) and SwaggerOption.IGNORING_HIDDEN_PROPERTIES was provided (i.e. this is an "opt-in")
    8. +
    9. Override a field's property name as per @ApiModelProperty(name = ...) if SwaggerOption.ENABLE_PROPERTY_NAME_OVERRIDES was provided (i.e. this is an "opt-in")
    10. +
    11. Indicate a number's (field/method) "minimum" (inclusive) according to @ApiModelProperty(allowableValues = "range[...")
    12. +
    13. Indicate a number's (field/method) "exclusiveMinimum" according to @ApiModelProperty(allowableValues = "range(...")
    14. +
    15. Indicate a number's (field/method) "maximum" (inclusive) according to @ApiModelProperty(allowableValues = "range...]")
    16. +
    17. Indicate a number's (field/method) "exclusiveMaximum" according to @ApiModelProperty(allowableValues = "range...)")
    18. +
    19. Indicate a field/method's "const"/"enum" as per @ApiModelProperty(allowableValues = ...) if it is not a numeric range declaration
    20. +
    + +

    Schema attributes derived from @ApiModelProperty on fields are also applied to their respective getter methods.
    +Schema attributes derived from @ApiModelProperty on getter methods are also applied to their associated fields.

    + +

    To use it, just pass a module instance into SchemaGeneratorConfigBuilder.with(Module), optionally providing SwaggerOption values in the module's constructor.

    +

    Swagger 2 Module

    +

    The victools:jsonschema-module-swagger-2 provides a number of standard configurations for deriving JSON Schema attributes from OpenAPI/swagger (2.x) @Schema annotations.

    +
    import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
    +import com.github.victools.jsonschema.generator.SchemaVersion;
    +import com.github.victools.jsonschema.module.swagger2.Swagger2Module;
    +
    +
    +Swagger2Module module = new Swagger2Module();
    +SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09)
    +    .with(module);
    +
    +
      +
    1. From @Schema(description = …) on types in general, derive "description".
    2. +
    3. From @Schema(title = …) on types in general, derive "title".
    4. +
    5. From @Schema(ref = …) on types in general, replace subschema with "$ref" to external/separate schema (except for the main type being targeted).
    6. +
    7. From @Schema(subTypes = …) on types in general, derive "anyOf" alternatives.
    8. +
    9. From @Schema(anyOf = …) on types in general (as alternative to subTypes), derive "anyOf" alternatives.
    10. +
    11. From @Schema(name = …) on types in general, derive the keys/names in "definitions"/"$defs".
    12. +
    13. From @Schema(description = …) on fields/methods, derive "description".
    14. +
    15. From @Schema(title = …) on fields/methods, derive "title".
    16. +
    17. From @Schema(implementation = …) on fields/methods, override represented type.
    18. +
    19. From @Schema(hidden = true) on fields/methods, skip certain properties.
    20. +
    21. From @Schema(name = …) on fields/methods, override property names.
    22. +
    23. From @Schema(ref = …) on fields/methods, replace subschema with "$ref" to external/separate schema.
    24. +
    25. From @Schema(allOf = …) on fields/methods, include "allOf" parts.
    26. +
    27. From @Schema(anyOf = …) on fields/methods, include "anyOf" parts.
    28. +
    29. From @Schema(oneOf = …) on fields/methods, include "oneOf" parts.
    30. +
    31. From @Schema(not = …) on fields/methods, include the indicated "not" subschema.
    32. +
    33. From @Schema(requiredMode = REQUIRED) or @Schema(required = true) on fields/methods, mark property as "required" in the schema containing the property.
    34. +
    35. From @Schema(requiredProperties = …) on fields/methods, derive its "required" properties.
    36. +
    37. From @Schema(minProperties = …) on fields/methods, derive its "minProperties".
    38. +
    39. From @Schema(maxProperties = …) on fields/methods, derive its "maxProperties".
    40. +
    41. From @Schema(nullable = true) on fields/methods, include null in its "type".
    42. +
    43. From @Schema(allowableValues = …) on fields/methods, derive its "const"/"enum".
    44. +
    45. From @Schema(defaultValue = …) on fields/methods, derive its "default".
    46. +
    47. From @Schema(accessMode = AccessMode.READ_ONLY) on fields/methods, to mark them as "readOnly".
    48. +
    49. From @Schema(accessMode = AccessMode.WRITE_ONLY) on fields/methods, to mark them as "writeOnly".
    50. +
    51. From @Schema(minLength = …) on fields/methods, derive its "minLength".
    52. +
    53. From @Schema(maxLength = …) on fields/methods, derive its "maxLength".
    54. +
    55. From @Schema(format = …) on fields/methods, derive its "format".
    56. +
    57. From @Schema(pattern = …) on fields/methods, derive its "pattern".
    58. +
    59. From @Schema(multipleOf = …) on fields/methods, derive its "multipleOf".
    60. +
    61. From @Schema(minimum = …, exclusiveMinimum = …) on fields/methods, derive its "minimum"/"exclusiveMinimum".
    62. +
    63. From @Schema(maximum = …, exclusiveMaximum = …) on fields/methods, derive its "maximum"/"exclusiveMaximum".
    64. +
    65. From @ArraySchema(minItems = …) on fields/methods, derive its "minItems".
    66. +
    67. From @ArraySchema(maxItems = …) on fields/methods, derive its "maxItems".
    68. +
    69. From @ArraySchema(uniqueItems = …) on fields/methods, derive its "uniqueItems".
    70. +
    + +

    Schema attributes derived from @Schema/@ArraySchema on fields are also applied to their respective getter methods. +Schema attributes derived from @Schema/@ArraySchema on getter methods are also applied to their associated fields.

    + +

    To use it, just pass a module instance into SchemaGeneratorConfigBuilder.with(Module).

    +

    Maven Plugin

    +

    The victools:jsonschema-maven-plugin allows you to incorporate the generation of JSON Schemas from your code into your build process. +There are a number of basic configuration options as well as the possibility to define any kind of configurations through a Module of your own.

    +

    Target Types to generate Schemas for

    <plugin>
    +    <groupId>com.github.victools</groupId>
    +    <artifactId>jsonschema-maven-plugin</artifactId>
    +    <executions>
    +        <execution>
    +            <goals>
    +                <goal>generate</goal>
    +            </goals>
    +        </execution>
    +    </executions>
    +    <configuration>
    +        <classNames>com/myOrg/myApp/My*</classNames>
    +        <packageNames>com/myOrg/myApp/package?</packageNames>
    +        <excludeClassNames>com/myOrg/myApp/**Hidden*</excludeClassNames>
    +        <annotations>
    +            <annotation>com.myOrg.MySchemaAnnotation</annotation>
    +        </annotations>
    +        <skipAbstractTypes>true</skipAbstractTypes>
    +        <skipInterfaces>true</skipInterfaces>
    +        <classpath>PROJECT_ONLY</classpath>
    +        <failIfNoClassesMatch>false</failIfNoClassesMatch>
    +    </configuration>
    +</plugin>
    +
    +

    The designated types can be mentioned separately (with dots as package separator) or in the form of glob patterns (with / as package separator) in <classNames> and/or included as part of their packages through <packageNames>. Through <excludeClassNames> you can further narrow down the type selection.
    +When specifying expected <annotations>, at least one of them need to be present on a given type to be considered – in addition to matching the aforementioned criteria, if those are present.
    +The considered <classpath> may be further specified as one of four values: +- PROJECT_ONLY : only source files of the current project +- WITH_COMPILE_DEPENDENCIES : PROJECT_ONLY and compile dependencies +- WITH_RUNTIME_DEPENDENCIES : PROJECT_ONLY and runtime dependencies (default, if unspecified) +- WITH_ALL_DEPENDENCIES : all of the above +- WITH_ALL_DEPENDENCIES_AND_TESTS : all of the above, with the addition of the current project's test files

    +

    Note that this requires a different <phase> (e.g., test-compile) being specified on the <execution>.

    +

    By default, the plugin aborts if the glob pattern does not match any class. If this is not desired, the <failIfNoClassesMatch> property can be set to false.

    +

    Basic Configuration Options

    +

    There are some additional parameters available in the plugin <configuration>:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #TagDefaultDescription
    1<schemaFilePath>src/main/resourcesDirectory to generate all schemas in
    2<schemaFileName>{0}-schema.jsonRelative path from the <schemaFilePath> including the file name pattern. Two placeholders are supported: {0} will be replaced with the respective simple class name (e.g. TypeA) {1} will be replaced with the respective package path (e.g. com/myOrg/myApp) in case you want to preserve the original package structure
    3<schemaVersion>DRAFT_7JSON Schema version to apply (DRAFT_6, DRAFT_7, DRAFT_2019_09 or DRAFT_2020_12)
    +

    Configuring generated file names and locations

    <configuration>
    +    <classNames>com.myOrg.myApp.MyClass</classNames>
    +    <schemaFilePath>src/main/resources/schemas</schemaFilePath>
    +</configuration>
    +
    +

    The location where the files will be generated can be specified with the <schemaFilePath> element. +The default path is src/main/resources

    +
    <configuration>
    +    <classNames>com.myOrg.myApp.MyClass</classNames>
    +    <schemaFileName>{0}.schema</schemaFileName>
    +</configuration>
    +
    +

    The name of the generated schema files can be configured with the <schemaFileName> element. +This is a substitution pattern that is used for all generated files. It is following the MessageFormat syntax, +where the following variables can be used: + - {0} : This is the name of the class + - {1} : This is the package path of the class

    + +

    For example, the given configuration will create a MyClass.schema file.

    +
    <configuration>
    +    <packageNames>com.myOrg.myApp.utils</packageNames>
    +    <schemaFileName>{1}/{0}.schema</schemaFileName>
    +</configuration>
    +
    +

    To store the generated schema files in the same directory structure as the originating classes, the following can be used <schemaFileName>{1}/{0}-schema.json</schemaFileName>.
    +The default <schemaFileName> is {0}-schema.json.

    + +

    Additionally, you can omit the generation for abstract classes and/or interfaces by setting the respective <skipAbstractTypes> or <skipInterfaces> flags to true (by default, they are false). +xml +<configuration> + <packageNames>com/myOrg/myApp/package/**</packageNames> + <skipAbstractTypes>true</skipAbstractTypes> + <skipInterfaces>true</skipInterfaces> +</configuration> +

    +

    Selecting Options

    <options>
    +    <preset>FULL_DOCUMENTATION</preset>
    +    <enabled>
    +        <option>DEFINITIONS_FOR_ALL_OBJECTS</option>
    +        <option>FORBIDDEN_ADDITIONAL_PROPERTIES_BY_DEFAULT</option>
    +    </enabled>
    +    <disabled>SCHEMA_VERSION_INDICATOR</disabled>
    +</options>
    +
    +

    The standard generator Options can be included via the <options> tag.

    +

    Further configurations through Modules

    <modules>
    +    <module>
    +        <name>Jackson</name>
    +        <options>
    +            <option>FLATTENED_ENUMS_FROM_JSONVALUE</option>
    +        </options>
    +    </module>
    +</modules>
    +
    +

    Through the <modules> tag you can include the standard modules – potentially with their <options> if there are any.

    +
    <modules>
    +    <module>
    +        <className>com.myOrg.myApp.CustomModule</className>
    +    </module>
    +</modules>
    +
    +

    You can also group any kind of configurations into a Module of your own and include it via its full class name.
    +Make sure your custom module is on the classpath (considering the project itself as well as all compile and runtime dependencies) and has a default constructor.
    +It is not possible to configure options for custom modules.

    +

    Altering the format of generated schema files

    public class MavenPluginYamlModule implements Module {
    +    @Override
    +    public void applyToConfigBuilder(SchemaGeneratorConfigBuilder builder) {
    +        // Maven plugin should produce YAML files instead of JSON
    +        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
    +        // set additional serialization options
    +        mapper.getSerializationConfig()
    +                .with(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS);
    +        mapper.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
    +        builder.withObjectMapper(mapper);
    +    }
    +}
    +
    +

    One possibility within such a custom Module (as mentioned above) is to configure the format of the generated schema files. +The file contents are being produced by the schema generator's associated ObjectMapper. +That default ObjectMapper can be replaced, e.g., to opt-out of the default pretty-printing or changing the file format to YAML. +The given example requires the inclusion of the extra com.fasterxml.jackson.dataformat:jackson-dataformat-yaml dependency.

    +

    Loading custom Module from test classes

    <executions>
    +    <execution>
    +        <phase>test-compile</phase>
    +        <goals>
    +            <goal>generate</goal>
    +        </goals>
    +    </execution>
    +</executions>
    +
    +

    When you're using a custom Module (as mentioned above) for additional configuration options, but don't want to include it among your application code, +you can either package it as separate artifact and include that as dependency of the plugin (not going into further detail here) +or the custom Module class can be included in your test packages.
    +When you do the latter, the Maven plugin will by default not be able to load that class, since it won't be compiled yet in the Maven phase during which the schema generation is being executed.
    +The Maven compile phase is when the schema generation gets triggered by default. +If you want the test classes (including the custom Module) to be available, a later phase (most likely: test-compile) needs to be specified.

    +

    FAQ

    Is there a Gradle Plugin?

    import com.github.victools.jsonschema.generator.OptionPreset;
    +import com.github.victools.jsonschema.generator.SchemaGenerator;
    +import com.github.victools.jsonschema.generator.SchemaGeneratorConfigBuilder;
    +import com.github.victools.jsonschema.generator.SchemaVersion;
    +
    +buildscript {
    +    repositories {
    +        mavenCentral()
    +    }
    +    dependencies {
    +        classpath group: 'com.github.victools', name: 'jsonschema-generator', version: '4.16.0'
    +    }
    +}
    +plugins {
    +    id 'java-library'
    +}
    +
    +task generate {
    +    doLast {
    +        def configBuilder = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON);
    +        // apply your configurations here
    +        def generator = new SchemaGenerator(configBuilder.build());
    +        // target the class for which to generate a schema
    +        def jsonSchema = generator.generateSchema(SchemaVersion.class);
    +        // handle generated schema, e.g. write it to the console or a file
    +        def jsonSchemaAsString = jsonSchema.toPrettyString();
    +        println jsonSchemaAsString
    +        new File(projectDir, "schema.json").text = jsonSchemaAsString
    +    }
    +}
    +
    +

    There currently is no dedicated Gradle Plugin as such, but Gradle is flexible enough to allow you to use a java library straight from within the build.gradle file. +Checkout https://github.com/victools/jsonschema-gradle-example for the complete example.

    +

    What about enums?

    +
    +

    If you have a custom serialization logic for converting enum values to strings, you can re-use it in order to generate the correct list of allowed values:

    +
    +
    ObjectMapper objectMapper = new ObjectMapper();
    +// make use of your enum handling e.g. through your own serializer
    +// objectMapper.registerModule(new YourCustomEnumSerializerModule());
    +configBuilder.with(new EnumModule(possibleEnumValue -> {
    +    try {
    +        String valueInQuotes = objectMapper.writeValueAsString(possibleEnumValue);
    +        return valueInQuotes.substring(1, valueInQuotes.length() - 1);
    +    } catch (JsonProcessingException ex) {
    +        throw new IllegalStateException(ex);
    +    }
    +}));
    +
    +

    Enums are a special construct for which there are multiple options:

    + +
      +
    1. Option.FLATTENED_ENUMS (which is part of the OptionPreset.PLAIN_JSON) + +
        +
      • This defines an enum as { "type": "string", "enum": ["VALUE1", "VALUE2"] } with the name() method being called on each possible enum value.
      • +
      • If there is only one enum value, it will be set as "const" instead.
      • +
      • Such an enum representation will always be in-lined and not moved into the "definitions"/"$defs".
      • +
    2. +
    3. Option.SIMPLIFIED_ENUMS(which is part of the OptionPreset.JAVA_OBJECT and OptionPreset.FULL_DOCUMENTATION) + +
        +
      • This treats enums like any other class but hiding some methods and listing the possible enum values as "enum"/"const" on the name() method.
      • +
    4. +
    5. Using neither of the two Options above will let them be handled like any other class (unless there are further configurations taking care of enums).
    6. +
    7. The JacksonModule comes with two more alternatives: + +
        +
      • JacksonOption.FLATTENED_ENUMS_FROM_JSONVALUE, behaving like Option.FLATTENED_ENUMS but looking-up the respective values via the @JsonValue annotated method.
      • +
      • JacksonOption.FLATTENED_ENUMS_FROM_JSONPROPERTY, behaving like Option.FLATTENED_ENUMS but looking-up the respective values via the @JsonProperty annotation on each enum value/constant.
      • +
    8. +
    9. Write your own custom definition provider or re-use the EnumModule class as in the shown example.
    10. +
    +

    How to always inline enums?

    class InlineAllEnumsDefinitionProvider implements CustomDefinitionProviderV2 {
    +    @Override
    +    public CustomDefinition provideCustomSchemaDefinition(ResolvedType javaType, SchemaGenerationContext context) {
    +        if (javaType.isInstanceOf(Enum.class)) {
    +            ObjectNode standardDefinition = context.createStandardDefinition(javaType, this);
    +            return new CustomDefinition(standardDefinition,
    +                    CustomDefinition.DefinitionType.INLINE,
    +                    CustomDefinition.AttributeInclusion.YES);
    +        }
    +        return null;
    +    }
    +}
    +
    configBuilder.forTypesInGeneral()
    +        .withCustomDefinitionProvider(new InlineAllEnumsDefinitionProvider())
    +
    +

    If you want to generally avoid that enums are being referenced via the $defs/definitions (even with active Option.DEFINITIONS_FOR_ALL_OBJECTS), a construct like the InlineAllEnumsDefinitionProvider on the right can be used.
    +As usual, such a Custom Type Definition can be added via configBuilder.forTypesInGeneral().withCustomDefinitionProvider() accordingly.

    +

    Where can I find some more configuration examples?

    +

    Internally, a number of the standard Options are realized via Individual Configurations and/or Advanced Configurations – grouped into Modules.
    +These make for excellent examples to get you started into your own setup, if the existing Options do not cover your specific requirements.

    +

    How to represent a Map<K, V> in a generated schema?

    configBuilder.forTypesInGeneral()
    +    .withPatternPropertiesResolver((scope) -> {
    +        if (scope.getType().isInstanceOf(Map.class)) {
    +            // within a Map<Key, Value> allow additional properties of the Value type, with purely alphabetic keys
    +            Map<String, Type> patternProperties = new HashMap<>();
    +            // theoretically, you could derive an appropriate schema from the key type, accessible via the same getTypeParameterFor() method
    +            // if no type parameters are defined, this will result in `{}` to be set as value schema and thereby allowing any values for matching keys
    +            patternProperties.put("^[a-zA-Z]+$", scope.getTypeParameterFor(Map.class, 1));
    +            return patternProperties;
    +        }
    +        return null;
    +    });
    +
    +

    By default, a Map will be treated like any other type – i.e. most likely a simple { "type": "object" } without many further details if you use the OptionPreset.PLAIN_JSON or otherwise ignore methods. +The following are the two most common approaches:

    + +
      +
    1. Indicate the value type V as the expected type for any "additionalProperties" by including the Option.MAP_VALUES_AS_ADDITIONAL_PROPERTIES.
      +You may also want to consider including the Option.FORBIDDEN_ADDITIONAL_PROPERTIES_BY_DEFAULT to forbid "additionalProperties" everywhere else.
    2. +
    3. If you have a clear idea of how the key type K will be serialized, you could also describe valid keys via "patternProperties" instead – as per the example on the right.
    4. +
    + +

    Refer to https://json-schema.org/understanding-json-schema/reference/regular_expressions.html for a description of how to build valid patterns.

    +

    How to populate default values?

    +
    +

    Example 1

    +
    +
    configBuilder.forFields().withDefaultResolver(field -> {
    +    JsonProperty annotation = field.getAnnotationConsideringFieldAndGetter(JsonProperty.class);
    +    return annotation == null || annotation.defaultValue().isEmpty() ? null : annotation.defaultValue();
    +});
    +
    +
    +

    Example 2

    +
    +
    ConcurrentMap<Class<?>, Object> instanceCache = new ConcurrentHashMap<>();
    +configBuilder.forFields().withDefaultResolver(field -> {
    +    Class<?> declaringClass = field.getDeclaringType().getErasedType();
    +    if (!field.isFakeContainerItemScope()
    +            && declaringClass.getName().startsWith("your.package")) {
    +        MethodScope getter = field.findGetter();
    +        if (getter != null) {
    +            try {
    +                Object instance = instanceCache.computeIfAbsent(declaringClass, declaringClass::newInstance);
    +                Object defaultValue = getter.getRawMember().invoke(instance);
    +                return defaultValue;
    +            } catch (Exception ex) {
    +                // most likely missing a no-args constructor
    +            }
    +        }
    +    }
    +    return null;
    +});
    +
    +

    The short answer is: via the withDefaultResolver() – one of the Individual Configurations.
    +The exact details depend on how the default value can be determined.

    + +
      +
    1. If the default value is explicitly stated via some kind of annotation, it might be as simple as "Example 1" on the right.
    2. +
    3. If the default value is only set in code, and you cannot or don't want to maintain that piece of information twice this can get a bit more advanced. Here assuming your own classes all have a default no-args constructor and conventional getters as in "Example 2" on the right.
    4. +
    +

    How to reference a separate schema/file?

    configBuilder.forTypesInGeneral()
    +        .withCustomDefinitionProvider((javaType, context) -> {
    +            if (javaType.getErasedType() != MyExternalType.class) {
    +                // other types should be treated normally
    +                return null;
    +            }
    +            // define your custom reference value
    +            String refValue = "./" + javaType.getErasedType().getSimpleName();
    +            // produce the sub-schema that only contains your custom reference
    +            ObjectNode customNode = context.getGeneratorConfig().createObjectNode()
    +                    .put(context.getKeyword(SchemaKeyword.TAG_REF), refValue);
    +            return new CustomDefinition(customNode,
    +                    // avoid the creation of a reference to your custom reference schema
    +                    CustomDefinition.DefinitionType.INLINE,
    +                    // still allow for collected schema attributes to be added
    +                    CustomDefinition.AttributeInclusion.YES);
    +        });
    +
    +

    By using withCustomDefinitionProvider() – one of the advanced configurations – you can fully control the contents of a type's sub-schema. +Simply create a node that only contains your custom/external reference instead of the actual schema. +It is recommended to mark the custom definition as "to be inlined", in order to avoid an extra entry in the "definitions"/"$defs".

    +

    Motivation

    +

    This started out as (and still is) a personal project. After writing Java code professionally for over a decade, +I am more and more consumed with rather theoretical work in my role as a business analyst and product owner – +i.e. writing specifications instead of code. However, my past still causes me to research available libraries and +components when coming up with ideas for new features, based on which I can then (at least try to) write "realistic" +specifications, i.e. features that can be feasibly implemented without requiring our developers to create something +from scratch (who'd want to spend their valuable time and resources for that?). Open Source is awesome! Unfortunately, +such research does not always yield satisfying results.

    + +

    The background for this particular requirement was very close to my heart as it affected me personally quite often. +I'm working at Torque IT Solutions – a small company that puts a lot of emphasis on providing software products instead +of building custom applications for each customer. That means, such a product needs to be generic enough to be a fit +for every customer. Amongst other things, we do this through heaps of configuration options. In order to achieve the +desired flexibility, these configurations are sometimes very technical. E.g. allowing our customers (i.e. users) to +define JavaScript expressions based on our own Java DOM. In reality this means quite often: customers can configure it +themselves but will still ask us/me to provide those expressions. However, that poses the challenge of documenting our +DOM in a way that it can be used without having access to the code itself or its JavaDoc. +I couldn't find a nice way of doing the above without sentencing myself to constantly maintain a huge amount of +documentation.

    + +

    It was development time again! I only needed to find some existing standard for documenting data structures (there +would surely be a way of automatically generating it from code then) and somehow visualize it, to allow non-developers +to use it. I quickly decided on the JSON Schema specification (although still in Draft version 6 then) and started +working on my react-jsonschema-inspector component. +While I had already spent considerable amounts of my spare time on this frontend component (my first ReactJS component +– I really missed the strong Java typing!), I realized that the existing JSON Schema generation libraries typically +expected some specific annotations throughout the code base for the sole purpose of generating a JSON Schema. I surely +wasn't expecting our developers to go through hundreds of classes and specifying schema parts (by this time Draft +version 7) throughout the codebase. And none of the existing generation libraries seemed to allow for methods to be +documented (understandable, if you only aim at documenting a JSON structure, but not good enough for my purposes after +all).

    + +

    Once more: development time! A new JSON Schema generation library needed to be created, as Open Source of course! At +least I was back in my familiar Java world. The whole topic of introspecting java types was a fun challenge that ended +in me adopting the use of the awesome com.fasterxml/classmate library – written by one of the maintainers of the +Jackson library, i.e. one who had worked with this kind of thing for a number of years already. +Then it was only about abstracting the actual schema generation from its configuration while still allowing almost all +aspects of the process to be customized to not force someone else to create yet another generation library just because +mine was too opinionated to be reusable (especially since Draft 2019-09 had just been published).

    + +

    In our existing codebase, we already had annotations for various purposes: Jackson annotations to facilitate the +(de)serialization for our Rest API, Swagger annotations to document that Rest API, javax.validation annotations for +realizing automatic validations of incoming data and during persistence. I very much liked the modular configuration +approach in Jackson so I ended up employing the same principle to wrap a few standard configurations for easier re-use. +Feedback from some early adopters led to those few standard configurations to be further extended – especially the +subtype resolution/polymorphism seemed to have been an important point also in the creation of other libraries, +e.g. for the mbknor-jackson-jsonSchema.

    + +
    +
    +
    +
    + + diff --git a/javascripts/all-e9bde216.js b/javascripts/all-e9bde216.js new file mode 100644 index 00000000..6e9e638b --- /dev/null +++ b/javascripts/all-e9bde216.js @@ -0,0 +1,120 @@ +function copyToClipboard(e){const t=document.createElement("textarea");t.value=e.textContent,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}function setupCodeCopy(){$("pre.highlight").prepend('
    Copy to Clipboard
    '),$(".copy-clipboard").on("click",function(){copyToClipboard(this.parentNode.children[1])})}function adjustLanguageSelectorWidth(){const e=$(".dark-box > .lang-selector");e.width(e.parent().width())}!function(){if("ontouchstart"in window){var e,t,n,r,i,o,s={};e=function(e,t){return Math.abs(e[0]-t[0])>5||Math.abs(e[1]-t[1])>5},t=function(e){this.startXY=[e.touches[0].clientX,e.touches[0].clientY],this.threshold=!1},n=function(t){if(this.threshold)return!1;this.threshold=e(this.startXY,[t.touches[0].clientX,t.touches[0].clientY])},r=function(t){if(!this.threshold&&!e(this.startXY,[t.changedTouches[0].clientX,t.changedTouches[0].clientY])){var n=t.changedTouches[0],r=document.createEvent("MouseEvents");r.initMouseEvent("click",!0,!0,window,0,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),r.simulated=!0,t.target.dispatchEvent(r)}},i=function(e){var t=Date.now(),n=t-s.time,r=e.clientX,i=e.clientY,a=[Math.abs(s.x-r),Math.abs(s.y-i)],u=o(e.target,"A")||e.target,l=u.nodeName,c="A"===l,f=window.navigator.standalone&&c&&e.target.getAttribute("href");if(s.time=t,s.x=r,s.y=i,(!e.simulated&&(n<500||n<1500&&a[0]<50&&a[1]<50)||f)&&(e.preventDefault(),e.stopPropagation(),!f))return!1;f&&(window.location=u.getAttribute("href")),u&&u.classList&&(u.classList.add("energize-focus"),window.setTimeout(function(){u.classList.remove("energize-focus")},150))},o=function(e,t){for(var n=e;n!==document.body;){if(!n||n.nodeName===t)return n;n=n.parentNode}return null},document.addEventListener("touchstart",t,!1),document.addEventListener("touchmove",n,!1),document.addEventListener("touchend",r,!1),document.addEventListener("click",i,!0)}}(),/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(e,t,n){n=n||we;var r,i,o=n.createElement("script");if(o.text=e,t)for(r in Te)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function r(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?pe[he.call(e)]||"object":typeof e}function i(e){var t=!!e&&"length"in e&&e.length,n=r(e);return!xe(e)&&!be(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function o(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}function s(e,t,n){return xe(t)?Ce.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?Ce.grep(e,function(e){return e===t!==n}):"string"!=typeof t?Ce.grep(e,function(e){return de.call(t,e)>-1!==n}):Ce.filter(t,e,n)}function a(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function u(e){var t={};return Ce.each(e.match(Pe)||[],function(e,n){t[n]=!0}),t}function l(e){return e}function c(e){throw e}function f(e,t,n,r){var i;try{e&&xe(i=e.promise)?i.call(e).done(t).fail(n):e&&xe(i=e.then)?i.call(e,t,n):t.apply(undefined,[e].slice(r))}catch(e){n.apply(undefined,[e])}}function d(){we.removeEventListener("DOMContentLoaded",d),e.removeEventListener("load",d),Ce.ready()}function p(e,t){return t.toUpperCase()}function h(e){return e.replace(Fe,"ms-").replace($e,p)}function g(){this.expando=Ce.expando+g.uid++}function m(e){return"true"===e||"false"!==e&&("null"===e?null:e===+e+""?+e:Be.test(e)?JSON.parse(e):e)}function y(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(We,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n=m(n)}catch(e){}Me.set(e,t,n)}else n=undefined;return n}function v(e,t,n,r){var i,o,s=20,a=r?function(){return r.cur()}:function(){return Ce.css(e,t,"")},u=a(),l=n&&n[3]||(Ce.cssNumber[t]?"":"px"),c=e.nodeType&&(Ce.cssNumber[t]||"px"!==l&&+u)&&Ve.exec(Ce.css(e,t));if(c&&c[3]!==l){for(u/=2,l=l||c[3],c=+u||1;s--;)Ce.style(e,t,c+l),(1-o)*(1-(o=a()/u||.5))<=0&&(s=0),c/=o;c*=2,Ce.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function x(e){var t,n=e.ownerDocument,r=e.nodeName,i=Ke[r];return i||(t=n.body.appendChild(n.createElement(r)),i=Ce.css(t,"display"),t.parentNode.removeChild(t),"none"===i&&(i="block"),Ke[r]=i,i)}function b(e,t){for(var n,r,i=[],o=0,s=e.length;o-1)o&&o.push(s);else if(c=Ye(s),a=w(d.appendChild(s),"script"),c&&T(a),n)for(f=0;s=a[f++];)tt.test(s.type||"")&&n.push(s);return d}function C(){return!0}function k(){return!1}function S(e,t){return e===L()==("focus"===t)}function L(){try{return we.activeElement}catch(e){}}function j(e,t,n,r,i,o){var s,a;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=undefined);for(a in t)j(e,a,n,r,t[a],o);return e}if(null==r&&null==i?(i=n,r=n=undefined):null==i&&("string"==typeof n?(i=r,r=undefined):(i=r,r=n,n=undefined)),!1===i)i=k;else if(!i)return e;return 1===o&&(s=i,i=function(e){return Ce().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=Ce.guid++)),e.each(function(){Ce.event.add(this,t,i,r,n)})}function N(e,t,n){if(!n)return void(He.get(e,t)===undefined&&Ce.event.add(e,t,C));He.set(e,t,!1),Ce.event.add(e,t,{namespace:!1,handler:function(e){var r,i,o=He.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(Ce.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=le.call(arguments),He.set(this,t,o),r=n(this,t),this[t](),i=He.get(this,t),o!==i||r?He.set(this,t,!1):i={},o!==i)return e.stopImmediatePropagation(),e.preventDefault(),i.value}else o.length&&(He.set(this,t,{value:Ce.event.trigger(Ce.extend(o[0],Ce.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})}function A(e,t){return o(e,"table")&&o(11!==t.nodeType?t:t.firstChild,"tr")?Ce(e).children("tbody")[0]||e:e}function D(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function I(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function O(e,t){var n,r,i,o,s,a,u;if(1===t.nodeType){if(He.hasData(e)&&(o=He.get(e),u=o.events)){He.remove(t,"handle events");for(i in u)for(n=0,r=u[i].length;n1&&"string"==typeof h&&!ve.checkClone&&ut.test(h))return e.each(function(n){var o=e.eq(n);g&&(t[0]=h.call(this,n,o.html())),Q(o,t,r,i)});if(d&&(o=E(t,e[0].ownerDocument,!1,e,i),s=o.firstChild,1===o.childNodes.length&&(o=s),s||i)){for(a=Ce.map(w(o,"script"),D),u=a.length;f=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-a-.5))||0),u}function B(e,t,n){var r=ft(e),i=!ve.boxSizingReliable()||n,s=i&&"border-box"===Ce.css(e,"boxSizing",!1,r),a=s,u=q(e,t,r),l="offset"+t[0].toUpperCase()+t.slice(1);if(ct.test(u)){if(!n)return u;u="auto"}return(!ve.boxSizingReliable()&&s||!ve.reliableTrDimensions()&&o(e,"tr")||"auto"===u||!parseFloat(u)&&"inline"===Ce.css(e,"display",!1,r))&&e.getClientRects().length&&(s="border-box"===Ce.css(e,"boxSizing",!1,r),(a=l in e)&&(u=e[l])),(u=parseFloat(u)||0)+M(e,t,n||(s?"border":"content"),a,r,u)+"px"}function W(e,t,n,r,i){return new W.prototype.init(e,t,n,r,i)}function z(){Tt&&(!1===we.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(z):e.setTimeout(z,Ce.fx.interval),Ce.fx.tick())}function V(){return e.setTimeout(function(){wt=undefined}),wt=Date.now()}function U(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)n=Ue[r],i["margin"+n]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function X(e,t,n){for(var r,i=(J.tweeners[t]||[]).concat(J.tweeners["*"]),o=0,s=i.length;o=0&&nE.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[_]=!0,e}function i(e){var t=O.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)E.attrHandle[n[r]]=t}function s(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function a(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&Se(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function c(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),s=o.length;s--;)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}function f(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function d(){}function p(e){for(var t=0,n=e.length,r="";t1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function m(e,n,r){for(var i=0,o=n.length;i-1&&(r[l]=!(s[l]=f))}}else x=y(x===s?x.splice(h,x.length):x),o?o(null,s,x,u):Z.apply(s,x)})}function x(e){for(var t,n,r,i=e.length,o=E.relative[e[0].type],s=o||E.relative[" "],a=o?1:0,u=h(function(e){return e===t},s,!0),l=h(function(e){return te(t,e)>-1},s,!0),c=[function(e,n,r){var i=!o&&(r||n!==N)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];a1&&g(c),a>1&&p(e.slice(0,a-1).concat({value:" "===e[a-2].type?"*":""})).replace(ue,"$1"),n,a0,o=e.length>0,s=function(r,s,a,u,l){var c,f,d,p=0,h="0",g=r&&[],m=[],v=N,x=r||o&&E.find.TAG("*",l),b=M+=null==v?1:Math.random()||.1,w=x.length;for(l&&(N=s==O||s||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,s||c.ownerDocument==O||(I(c),a=!Q);d=e[f++];)if(d(c,s||O,a)){u.push(c);break}l&&(M=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,m,s,a);if(r){if(p>0)for(;h--;)g[h]||m[h]||(m[h]=J.call(u));m=y(m)}Z.apply(u,m),l&&!r&&m.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(M=b,N=v),g};return i?r(s):s}var w,T,E,C,k,S,L,j,N,A,D,I,O,P,Q,R,q,F,$,_="sizzle"+1*new Date,H=e.document,M=0,B=0,W=n(),z=n(),V=n(),U=n(),X=function(e,t){return e===t&&(D=!0),0},Y={}.hasOwnProperty,G=[],J=G.pop,K=G.push,Z=G.push,ee=G.slice,te=function(e,t){for(var n=0,r=e.length;n+~]|"+re+")"+re+"*"),fe=new RegExp(re+"|>"),de=new RegExp(se),pe=new RegExp("^"+ie+"$"),he={ID:new RegExp("^#("+ie+")"),CLASS:new RegExp("^\\.("+ie+")"),TAG:new RegExp("^("+ie+"|[*])"),ATTR:new RegExp("^"+oe),PSEUDO:new RegExp("^"+se),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+re+"*(even|odd|(([+-]|)(\\d*)n|)"+re+"*(?:([+-]|)"+re+"*(\\d+)|))"+re+"*\\)|)","i"),bool:new RegExp("^(?:"+ne+")$","i"),needsContext:new RegExp("^"+re+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+re+"*((?:-\\d)?\\d*)"+re+"*\\)|)(?=[^-]|$)","i")},ge=/HTML$/i,me=/^(?:input|select|textarea|button)$/i,ye=/^h\d$/i,ve=/^[^{]+\{\s*\[native \w/,xe=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,be=/[+~]/,we=new RegExp("\\\\[\\da-fA-F]{1,6}"+re+"?|\\\\([^\\r\\n\\f])","g"),Te=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},Ee=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,Ce=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},ke=function(){I()},Se=h(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{Z.apply(G=ee.call(H.childNodes),H.childNodes),G[H.childNodes.length].nodeType}catch(e){Z={apply:G.length?function(e,t){K.apply(e,ee.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}T=t.support={},k=t.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!ge.test(t||n&&n.nodeName||"HTML")},I=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:H;return r!=O&&9===r.nodeType&&r.documentElement?(O=r,P=O.documentElement,Q=!k(O),H!=O&&(n=O.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",ke,!1):n.attachEvent&&n.attachEvent("onunload",ke)),T.scope=i(function(e){return P.appendChild(e).appendChild(O.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),T.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),T.getElementsByTagName=i(function(e){return e.appendChild(O.createComment("")),!e.getElementsByTagName("*").length}),T.getElementsByClassName=ve.test(O.getElementsByClassName),T.getById=i(function(e){return P.appendChild(e).id=_,!O.getElementsByName||!O.getElementsByName(_).length}),T.getById?(E.filter.ID=function(e){var t=e.replace(we,Te);return function(e){return e.getAttribute("id")===t}},E.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&Q){var n=t.getElementById(e);return n?[n]:[]}}):(E.filter.ID=function(e){var t=e.replace(we,Te);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},E.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&Q){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),E.find.TAG=T.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):T.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},E.find.CLASS=T.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&Q)return t.getElementsByClassName(e)},q=[],R=[],(T.qsa=ve.test(O.querySelectorAll))&&(i(function(e){var t;P.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&R.push("[*^$]="+re+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||R.push("\\["+re+"*(?:value|"+ne+")"),e.querySelectorAll("[id~="+_+"-]").length||R.push("~="),t=O.createElement("input"),t.setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||R.push("\\["+re+"*name"+re+"*="+re+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||R.push(":checked"),e.querySelectorAll("a#"+_+"+*").length||R.push(".#.+[+~]"),e.querySelectorAll("\\\f"),R.push("[\\r\\n\\f]")}),i(function(e){e.innerHTML="";var t=O.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&R.push("name"+re+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&R.push(":enabled",":disabled"),P.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&R.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),R.push(",.*:")})),(T.matchesSelector=ve.test(F=P.matches||P.webkitMatchesSelector||P.mozMatchesSelector||P.oMatchesSelector||P.msMatchesSelector))&&i(function(e){T.disconnectedMatch=F.call(e,"*"),F.call(e,"[s!='']:x"),q.push("!=",se)}),R=R.length&&new RegExp(R.join("|")),q=q.length&&new RegExp(q.join("|")),t=ve.test(P.compareDocumentPosition),$=t||ve.test(P.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},X=t?function(e,t){if(e===t)return D=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!T.sortDetached&&t.compareDocumentPosition(e)===n?e==O||e.ownerDocument==H&&$(H,e)?-1:t==O||t.ownerDocument==H&&$(H,t)?1:A?te(A,e)-te(A,t):0:4&n?-1:1)}:function(e,t){if(e===t)return D=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],u=[t];if(!i||!o)return e==O?-1:t==O?1:i?-1:o?1:A?te(A,e)-te(A,t):0;if(i===o)return s(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;a[r]===u[r];)r++;return r?s(a[r],u[r]):a[r]==H?-1:u[r]==H?1:0},O):O},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if(I(e),T.matchesSelector&&Q&&!U[n+" "]&&(!q||!q.test(n))&&(!R||!R.test(n)))try{var r=F.call(e,n);if(r||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){U(n,!0)}return t(n,O,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!=O&&I(e),$(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!=O&&I(e);var n=E.attrHandle[t.toLowerCase()],r=n&&Y.call(E.attrHandle,t.toLowerCase())?n(e,t,!Q):undefined;return r!==undefined?r:T.attributes||!Q?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.escape=function(e){return(e+"").replace(Ee,Ce)},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(D=!T.detectDuplicates,A=!T.sortStable&&e.slice(0),e.sort(X),D){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return A=null,e},C=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},E=t.selectors={cacheLength:50,createPseudo:r,match:he,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(we,Te),e[3]=(e[3]||e[4]||e[5]||"").replace(we,Te),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return he.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&de.test(n)&&(t=S(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(we,Te).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=W[e+" "];return t||(t=new RegExp("(^|"+re+")"+e+"("+re+"|$)"))&&W(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ae," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,y=a&&t.nodeName.toLowerCase(),v=!u&&!a,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(a?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[s?m.firstChild:m.lastChild],s&&v){for(d=m,f=d[_]||(d[_]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===M&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[M,p,x];break}}else if(v&&(d=t,f=d[_]||(d[_]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===M&&l[1],x=p),!1===x)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((a?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[_]||(d[_]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[M,x]),d!==t)););return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=E.pseudos[e]||E.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[_]?o(n):o.length>1?(i=[e,e,"",n],E.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),s=i.length;s--;)r=te(e,i[s]),e[r]=!(t[r]=i[s])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=L(e.replace(ue,"$1"));return i[_]?r(function(e,t,n,r){for(var o,s=i(e,null,r,[]),a=e.length;a--;)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(we,Te),function(t){return(t.textContent||C(t)).indexOf(e)>-1}}),lang:r(function(e){return pe.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(we,Te).toLowerCase(),function(t){var n;do{if(n=Q?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===P},focus:function(e){return e===O.activeElement&&(!O.hasFocus||O.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:l(!1),disabled:l(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!E.pseudos.empty(e)},header:function(e){return ye.test(e.nodeName)},input:function(e){return me.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:c(function(){return[0]}),last:c(function(e,t){return[t-1]}),eq:c(function(e,t,n){return[n<0?n+t:n]}),even:c(function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e}),gt:c(function(e,t,n){for(var r=n<0?n+t:n;++r2&&"ID"===(s=o[0]).type&&9===t.nodeType&&Q&&E.relative[o[1].type]){if(!(t=(E.find.ID(s.matches[0].replace(we,Te),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=he.needsContext.test(e)?0:o.length;i--&&(s=o[i],!E.relative[a=s.type]);)if((u=E.find[a])&&(r=u(s.matches[0].replace(we,Te),be.test(o[0].type)&&f(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&p(o)))return Z.apply(n,r),n;break}}return(l||L(e,c))(r,t,!Q,n,!t||be.test(e)&&f(t.parentNode)||t),n},T.sortStable=_.split("").sort(X).join("")===_,T.detectDuplicates=!!D,I(),T.sortDetached=i(function(e){return 1&e.compareDocumentPosition(O.createElement("fieldset"))}),i(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),T.attributes&&i(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(ne,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);Ce.find=ke,Ce.expr=ke.selectors,Ce.expr[":"]=Ce.expr.pseudos,Ce.uniqueSort=Ce.unique=ke.uniqueSort,Ce.text=ke.getText,Ce.isXMLDoc=ke.isXML,Ce.contains=ke.contains,Ce.escapeSelector=ke.escape;var Se=function(e,t,n){for(var r=[],i=n!==undefined;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&Ce(e).is(n))break;r.push(e)}return r},Le=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},je=Ce.expr.match.needsContext,Ne=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;Ce.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?Ce.find.matchesSelector(r,e)?[r]:[]:Ce.find.matches(e,Ce.grep(t,function(e){return 1===e.nodeType}))},Ce.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(Ce(e).filter(function(){for(t=0;t1?Ce.uniqueSort(n):n},filter:function(e){return this.pushStack(s(this,e||[],!1))},not:function(e){return this.pushStack(s(this,e||[],!0))},is:function(e){return!!s(this,"string"==typeof e&&je.test(e)?Ce(e):e||[],!1).length}});var Ae,De=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(Ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ae,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:De.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof Ce?t[0]:t,Ce.merge(this,Ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:we,!0)),Ne.test(r[1])&&Ce.isPlainObject(t))for(r in t)xe(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=we.getElementById(r[2]),i&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):xe(e)?n.ready!==undefined?n.ready(e):e(Ce):Ce.makeArray(e,this)}).prototype=Ce.fn,Ae=Ce(we);var Ie=/^(?:parents|prev(?:Until|All))/,Oe={children:!0,contents:!0,next:!0,prev:!0};Ce.fn.extend({has:function(e){var t=Ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&Ce.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?Ce.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?de.call(Ce(e),this[0]):de.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(Ce.uniqueSort(Ce.merge(this.get(),Ce(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),Ce.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return Se(e,"parentNode")},parentsUntil:function(e,t,n){return Se(e,"parentNode",n)},next:function(e){return a(e,"nextSibling")},prev:function(e){return a(e,"previousSibling")},nextAll:function(e){return Se(e,"nextSibling")},prevAll:function(e){return Se(e,"previousSibling")},nextUntil:function(e,t,n){return Se(e,"nextSibling",n)},prevUntil:function(e,t,n){return Se(e,"previousSibling",n)},siblings:function(e){return Le((e.parentNode||{}).firstChild,e)},children:function(e){return Le(e.firstChild)},contents:function(e){return null!=e.contentDocument&&ue(e.contentDocument)?e.contentDocument:(o(e,"template")&&(e=e.content||e),Ce.merge([],e.childNodes))}},function(e,t){Ce.fn[e]=function(n,r){var i=Ce.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=Ce.filter(r,i)),this.length>1&&(Oe[e]||Ce.uniqueSort(i),Ie.test(e)&&i.reverse()),this.pushStack(i)}});var Pe=/[^\x20\t\r\n\f]+/g;Ce.Callbacks=function(e){e="string"==typeof e?u(e):Ce.extend({},e);var t,n,i,o,s=[],a=[],l=-1,c=function(){for(o=o||e.once,i=t=!0;a.length;l=-1)for(n=a.shift();++l-1;)s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?Ce.inArray(e,s)>-1:s.length>0},empty:function(){return s&&(s=[]),this},disable:function(){return o=a=[],s=n="",this},disabled:function(){return!s},lock:function(){return o=a=[],n||t||(s=n=""),this},locked:function(){return!!o},fireWith:function(e,n){return o||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!i}};return f},Ce.extend({Deferred:function(t){var n=[["notify","progress",Ce.Callbacks("memory"),Ce.Callbacks("memory"),2],["resolve","done",Ce.Callbacks("once memory"),Ce.Callbacks("once memory"),0,"resolved"],["reject","fail",Ce.Callbacks("once memory"),Ce.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return Ce.Deferred(function(t){Ce.each(n,function(n,r){var i=xe(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&xe(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){function o(t,n,r,i){return function(){var a=this,u=arguments,f=function(){var e,f;if(!(t=s&&(r!==c&&(a=undefined,u=[e]),n.rejectWith(a,u))}};t?d():(Ce.Deferred.getStackHook&&(d.stackTrace=Ce.Deferred.getStackHook()),e.setTimeout(d))}}var s=0;return Ce.Deferred(function(e){n[0][3].add(o(0,e,xe(i)?i:l,e.notifyWith)),n[1][3].add(o(0,e,xe(t)?t:l)),n[2][3].add(o(0,e,xe(r)?r:c))}).promise()},promise:function(e){return null!=e?Ce.extend(e,i):i}},o={};return Ce.each(n,function(e,t){var s=t[2],a=t[5];i[t[1]]=s.add,a&&s.add(function(){r=a},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),s.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?undefined:this,arguments),this},o[t[0]+"With"]=s.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=le.call(arguments),o=Ce.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?le.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(f(e,o.done(s(n)).resolve,o.reject,!t),"pending"===o.state()||xe(i[n]&&i[n].then)))return o.then();for(;n--;)f(i[n],s(n),o.reject);return o.promise()}});var Qe=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;Ce.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&Qe.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},Ce.readyException=function(t){e.setTimeout(function(){throw t})};var Re=Ce.Deferred();Ce.fn.ready=function(e){return Re.then(e)["catch"](function(e){Ce.readyException(e)}),this},Ce.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--Ce.readyWait:Ce.isReady)||(Ce.isReady=!0,!0!==e&&--Ce.readyWait>0||Re.resolveWith(we,[Ce]))}}),Ce.ready.then=Re.then,"complete"===we.readyState||"loading"!==we.readyState&&!we.documentElement.doScroll?e.setTimeout(Ce.ready):(we.addEventListener("DOMContentLoaded",d),e.addEventListener("load",d));var qe=function(e,t,n,i,o,s,a){var u=0,l=e.length,c=null==n;if("object"===r(n)){o=!0;for(u in n)qe(e,t,u,n[u],!0,s,a)}else if(i!==undefined&&(o=!0,xe(i)||(a=!0),c&&(a?(t.call(e,i),t=null):(c=t,t=function(e,t,n){return c.call(Ce(e),n)})),t))for(;u1,null,!0)},removeData:function(e){return this.each(function(){Me.remove(this,e)})}}),Ce.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=He.get(e,t),n&&(!r||Array.isArray(n)?r=He.access(e,t,Ce.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=Ce.queue(e,t),r=n.length,i=n.shift(),o=Ce._queueHooks(e,t),s=function(){Ce.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return He.get(e,n)||He.access(e,n,{empty:Ce.Callbacks("once memory").add(function(){He.remove(e,[t+"queue",n])})})}}),Ce.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,tt=/^$|^module$|\/(?:java|ecma)script/i;!function(){var e=we.createDocumentFragment(),t=e.appendChild(we.createElement("div")),n=we.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),ve.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",ve.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue,t.innerHTML="",ve.option=!!t.lastChild}();var nt={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]} +;nt.tbody=nt.tfoot=nt.colgroup=nt.caption=nt.thead,nt.th=nt.td,ve.option||(nt.optgroup=nt.option=[1,""]);var rt=/<|&#?\w+;/,it=/^key/,ot=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,st=/^([^.]*)(?:\.(.+)|)/;Ce.event={global:{},add:function(e,t,n,r,i){var o,s,a,u,l,c,f,d,p,h,g,m=He.get(e);if(_e(e))for(n.handler&&(o=n,n=o.handler,i=o.selector),i&&Ce.find.matchesSelector(Xe,i),n.guid||(n.guid=Ce.guid++),(u=m.events)||(u=m.events=Object.create(null)),(s=m.handle)||(s=m.handle=function(t){return void 0!==Ce&&Ce.event.triggered!==t.type?Ce.event.dispatch.apply(e,arguments):undefined}),t=(t||"").match(Pe)||[""],l=t.length;l--;)a=st.exec(t[l])||[],p=g=a[1],h=(a[2]||"").split(".").sort(),p&&(f=Ce.event.special[p]||{},p=(i?f.delegateType:f.bindType)||p,f=Ce.event.special[p]||{},c=Ce.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&Ce.expr.match.needsContext.test(i),namespace:h.join(".")},o),(d=u[p])||(d=u[p]=[],d.delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,s)||e.addEventListener&&e.addEventListener(p,s)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),Ce.event.global[p]=!0)},remove:function(e,t,n,r,i){var o,s,a,u,l,c,f,d,p,h,g,m=He.hasData(e)&&He.get(e);if(m&&(u=m.events)){for(t=(t||"").match(Pe)||[""],l=t.length;l--;)if(a=st.exec(t[l])||[],p=g=a[1],h=(a[2]||"").split(".").sort(),p){for(f=Ce.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=u[p]||[],a=a[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=d.length;o--;)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,f.remove&&f.remove.call(e,c));s&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,h,m.handle)||Ce.removeEvent(e,p,m.handle),delete u[p])}else for(p in u)Ce.event.remove(e,p+t[l],n,r,!0);Ce.isEmptyObject(u)&&He.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,s,a=new Array(arguments.length),u=Ce.event.fix(e),l=(He.get(this,"events")||Object.create(null))[u.type]||[],c=Ce.event.special[u.type]||{};for(a[0]=u,t=1;t=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],s={},n=0;n-1:Ce.find(i,this,null,[l]).length),s[i]&&o.push(r);o.length&&a.push({elem:l,handlers:o})}return l=this,u\s*$/g;Ce.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=Ye(e);if(!(ve.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||Ce.isXMLDoc(e)))for(s=w(a),o=w(e),r=0,i=o.length;r0&&T(s,!u&&w(e,"script")),a},cleanData:function(e){for(var t,n,r,i=Ce.event.special,o=0;(n=e[o])!==undefined;o++)if(_e(n)){if(t=n[He.expando]){if(t.events)for(r in t.events)i[r]?Ce.event.remove(n,r):Ce.removeEvent(n,r,t.handle);n[He.expando]=undefined}n[Me.expando]&&(n[Me.expando]=undefined)}}}),Ce.fn.extend({detach:function(e){return R(this,e,!0)},remove:function(e){return R(this,e)},text:function(e){return qe(this,function(e){return e===undefined?Ce.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Q(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){A(this,e).appendChild(e)}})},prepend:function(){return Q(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=A(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Q(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Q(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(Ce.cleanData(w(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return Ce.clone(this,e,t)})},html:function(e){return qe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!at.test(e)&&!nt[(et.exec(e)||["",""])[1].toLowerCase()]){e=Ce.htmlPrefilter(e);try{for(;n3,Xe.removeChild(t)),a}}))}();var ht=["Webkit","Moz","ms"],gt=we.createElement("div").style,mt={},yt=/^(none|table(?!-c[ea]).+)/,vt=/^--/,xt={position:"absolute",visibility:"hidden",display:"block"},bt={letterSpacing:"0",fontWeight:"400"};Ce.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=q(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=h(t),u=vt.test(t),l=e.style;if(u||(t=_(a)),s=Ce.cssHooks[t]||Ce.cssHooks[a],n===undefined)return s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:l[t];o=typeof n,"string"===o&&(i=Ve.exec(n))&&i[1]&&(n=v(e,t,i),o="number"),null!=n&&n===n&&("number"!==o||u||(n+=i&&i[3]||(Ce.cssNumber[a]?"":"px")),ve.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,s,a=h(t);return vt.test(t)||(t=_(a)),s=Ce.cssHooks[t]||Ce.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=q(e,t,r)),"normal"===i&&t in bt&&(i=bt[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),Ce.each(["height","width"],function(e,t){Ce.cssHooks[t]={get:function(e,n,r){if(n)return!yt.test(Ce.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?B(e,t,r):dt(e,xt,function(){return B(e,t,r)})},set:function(e,n,r){var i,o=ft(e),s=!ve.scrollboxSize()&&"absolute"===o.position,a=s||r,u=a&&"border-box"===Ce.css(e,"boxSizing",!1,o),l=r?M(e,t,r,u,o):0;return u&&s&&(l-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-M(e,t,"border",!1,o)-.5)),l&&(i=Ve.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=Ce.css(e,t)),H(e,n,l)}}}),Ce.cssHooks.marginLeft=F(ve.reliableMarginLeft,function(e,t){if(t)return(parseFloat(q(e,"marginLeft"))||e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),Ce.each({margin:"",padding:"",border:"Width"},function(e,t){Ce.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+Ue[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(Ce.cssHooks[e+t].set=H)}),Ce.fn.extend({css:function(e,t){return qe(this,function(e,t,n){var r,i,o={},s=0;if(Array.isArray(t)){for(r=ft(e),i=t.length;s1)}}),Ce.Tween=W,W.prototype={constructor:W,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||Ce.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(Ce.cssNumber[n]?"":"px")},cur:function(){var e=W.propHooks[this.prop];return e&&e.get?e.get(this):W.propHooks._default.get(this)},run:function(e){var t,n=W.propHooks[this.prop];return this.options.duration?this.pos=t=Ce.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):W.propHooks._default.set(this),this}},W.prototype.init.prototype=W.prototype,W.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=Ce.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){Ce.fx.step[e.prop]?Ce.fx.step[e.prop](e):1!==e.elem.nodeType||!Ce.cssHooks[e.prop]&&null==e.elem.style[_(e.prop)]?e.elem[e.prop]=e.now:Ce.style(e.elem,e.prop,e.now+e.unit)}}},W.propHooks.scrollTop=W.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},Ce.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},Ce.fx=W.prototype.init,Ce.fx.step={};var wt,Tt,Et=/^(?:toggle|show|hide)$/,Ct=/queueHooks$/;Ce.Animation=Ce.extend(J,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return v(n.elem,e,Ve.exec(t),n),n}]},tweener:function(e,t){xe(e)?(t=e,e=["*"]):e=e.match(Pe);for(var n,r=0,i=e.length;r1)},removeAttr:function(e){return this.each(function(){Ce.removeAttr(this,e)})}}),Ce.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?Ce.prop(e,t,n):(1===o&&Ce.isXMLDoc(e)||(i=Ce.attrHooks[t.toLowerCase()]||(Ce.expr.match.bool.test(t)?kt:undefined)),n!==undefined?null===n?void Ce.removeAttr(e,t):i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=Ce.find.attr(e,t),null==r?undefined:r))},attrHooks:{type:{set:function(e,t){if(!ve.radioValue&&"radio"===t&&o(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(Pe);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),kt={set:function(e,t,n){return!1===t?Ce.removeAttr(e,n):e.setAttribute(n,n),n}},Ce.each(Ce.expr.match.bool.source.match(/\w+/g),function(e,t){var n=St[t]||Ce.find.attr;St[t]=function(e,t,r){var i,o,s=t.toLowerCase();return r||(o=St[s],St[s]=i,i=null!=n(e,t,r)?s:null,St[s]=o),i}});var Lt=/^(?:input|select|textarea|button)$/i,jt=/^(?:a|area)$/i;Ce.fn.extend({prop:function(e,t){return qe(this,Ce.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[Ce.propFix[e]||e]})}}),Ce.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&Ce.isXMLDoc(e)||(t=Ce.propFix[t]||t,i=Ce.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=Ce.find.attr(e,"tabindex");return t?parseInt(t,10):Lt.test(e.nodeName)||jt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),ve.optSelected||(Ce.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),Ce.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){Ce.propFix[this.toLowerCase()]=this}),Ce.fn.extend({addClass:function(e){var t,n,r,i,o,s,a,u=0;if(xe(e))return this.each(function(t){Ce(this).addClass(e.call(this,t,Z(this)))});if(t=ee(e),t.length)for(;n=this[u++];)if(i=Z(n),r=1===n.nodeType&&" "+K(i)+" "){for(s=0;o=t[s++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");a=K(r),i!==a&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,r,i,o,s,a,u=0;if(xe(e))return this.each(function(t){Ce(this).removeClass(e.call(this,t,Z(this)))});if(!arguments.length)return this.attr("class","");if(t=ee(e),t.length)for(;n=this[u++];)if(i=Z(n),r=1===n.nodeType&&" "+K(i)+" "){for(s=0;o=t[s++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");a=K(r),i!==a&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):xe(e)?this.each(function(n){Ce(this).toggleClass(e.call(this,n,Z(this),t),t)}):this.each(function(){var t,i,o,s;if(r)for(i=0,o=Ce(this),s=ee(e);t=s[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else e!==undefined&&"boolean"!==n||(t=Z(this),t&&He.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":He.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+K(Z(n))+" ").indexOf(t)>-1)return!0;return!1}});var Nt=/\r/g;Ce.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=xe(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,Ce(this).val()):e,null==i?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=Ce.map(i,function(e){return null==e?"":e+""})),(t=Ce.valHooks[this.type]||Ce.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return(t=Ce.valHooks[i.type]||Ce.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace(Nt,""):null==n?"":n)}}}),Ce.extend({valHooks:{option:{get:function(e){var t=Ce.find.attr(e,"value");return null!=t?t:K(Ce.text(e))}},select:{get:function(e){var t,n,r,i=e.options,s=e.selectedIndex,a="select-one"===e.type,u=a?null:[],l=a?s+1:i.length;for(r=s<0?l:a?s:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),Ce.each(["radio","checkbox"],function(){Ce.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=Ce.inArray(Ce(e).val(),t)>-1}},ve.checkOn||(Ce.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),ve.focusin="onfocusin"in e;var At=/^(?:focusinfocus|focusoutblur)$/,Dt=function(e){e.stopPropagation()};Ce.extend(Ce.event,{trigger:function(t,n,r,i){var o,s,a,u,l,c,f,d,p=[r||we],h=ge.call(t,"type")?t.type:t,g=ge.call(t,"namespace")?t.namespace.split("."):[];if(s=d=a=r=r||we,3!==r.nodeType&&8!==r.nodeType&&!At.test(h+Ce.event.triggered)&&(h.indexOf(".")>-1&&(g=h.split("."),h=g.shift(),g.sort()),l=h.indexOf(":")<0&&"on"+h,t=t[Ce.expando]?t:new Ce.Event(h,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:Ce.makeArray(n,[t]),f=Ce.event.special[h]||{},i||!f.trigger||!1!==f.trigger.apply(r,n))){if(!i&&!f.noBubble&&!be(r)){for(u=f.delegateType||h,At.test(u+h)||(s=s.parentNode);s;s=s.parentNode)p.push(s),a=s;a===(r.ownerDocument||we)&&p.push(a.defaultView||a.parentWindow||e)}for(o=0;(s=p[o++])&&!t.isPropagationStopped();)d=s,t.type=o>1?u:f.bindType||h,c=(He.get(s,"events")||Object.create(null))[t.type]&&He.get(s,"handle"),c&&c.apply(s,n),(c=l&&s[l])&&c.apply&&_e(s)&&(t.result=c.apply(s,n),!1===t.result&&t.preventDefault());return t.type=h,i||t.isDefaultPrevented()||f._default&&!1!==f._default.apply(p.pop(),n)||!_e(r)||l&&xe(r[h])&&!be(r)&&(a=r[l],a&&(r[l]=null),Ce.event.triggered=h,t.isPropagationStopped()&&d.addEventListener(h,Dt),r[h](),t.isPropagationStopped()&&d.removeEventListener(h,Dt),Ce.event.triggered=undefined,a&&(r[l]=a)),t.result}},simulate:function(e,t,n){var r=Ce.extend(new Ce.Event,n,{type:e,isSimulated:!0});Ce.event.trigger(r,null,t)}}),Ce.fn.extend({trigger:function(e,t){return this.each(function(){Ce.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return Ce.event.trigger(e,t,n,!0)}}),ve.focusin||Ce.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){Ce.event.simulate(t,e.target,Ce.event.fix(e))};Ce.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,i=He.access(r,t);i||r.addEventListener(e,n,!0),He.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,i=He.access(r,t)-1;i?He.access(r,t,i):(r.removeEventListener(e,n,!0),He.remove(r,t))}}});var It=e.location,Ot={guid:Date.now()},Pt=/\?/;Ce.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=undefined}return n&&!n.getElementsByTagName("parsererror").length||Ce.error("Invalid XML: "+t),n};var Qt=/\[\]$/,Rt=/\r?\n/g,qt=/^(?:submit|button|image|reset|file)$/i,Ft=/^(?:input|select|textarea|keygen)/i;Ce.param=function(e,t){var n,r=[],i=function(e,t){var n=xe(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!Ce.isPlainObject(e))Ce.each(e,function(){i(this.name,this.value)});else for(n in e)te(n,e[n],t,i);return r.join("&")},Ce.fn.extend({serialize:function(){return Ce.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=Ce.prop(this,"elements");return e?Ce.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!Ce(this).is(":disabled")&&Ft.test(this.nodeName)&&!qt.test(e)&&(this.checked||!Ze.test(e))}).map(function(e,t){var n=Ce(this).val();return null==n?null:Array.isArray(n)?Ce.map(n,function(e){return{name:t.name,value:e.replace(Rt,"\r\n")}}):{name:t.name,value:n.replace(Rt,"\r\n")}}).get()}});var $t=/%20/g,_t=/#.*$/,Ht=/([?&])_=[^&]*/,Mt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Bt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Wt=/^(?:GET|HEAD)$/,zt=/^\/\//,Vt={},Ut={},Xt="*/".concat("*"),Yt=we.createElement("a");Yt.href=It.href,Ce.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:It.href,type:"GET",isLocal:Bt.test(It.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Xt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":Ce.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?ie(ie(e,Ce.ajaxSettings),t):ie(Ce.ajaxSettings,e)},ajaxPrefilter:ne(Vt),ajaxTransport:ne(Ut),ajax:function(t,n){function r(t,n,r,a){var l,d,p,b,w,T=n;c||(c=!0,u&&e.clearTimeout(u),i=undefined,s=a||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=oe(h,E,r)),!l&&Ce.inArray("script",h.dataTypes)>-1&&(h.converters["text script"]=function(){}),b=se(h,b,E,l),l?(h.ifModified&&(w=E.getResponseHeader("Last-Modified"),w&&(Ce.lastModified[o]=w),(w=E.getResponseHeader("etag"))&&(Ce.etag[o]=w)),204===t||"HEAD"===h.type?T="nocontent":304===t?T="notmodified":(T=b.state,d=b.data,p=b.error,l=!p)):(p=T,!t&&T||(T="error",t<0&&(t=0))),E.status=t,E.statusText=(n||T)+"",l?y.resolveWith(g,[d,T,E]):y.rejectWith(g,[E,T,p]),E.statusCode(x),x=undefined,f&&m.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?d:p]),v.fireWith(g,[E,T]),f&&(m.trigger("ajaxComplete",[E,h]),--Ce.active||Ce.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=undefined),n=n||{};var i,o,s,a,u,l,c,f,d,p,h=Ce.ajaxSetup({},n),g=h.context||h,m=h.context&&(g.nodeType||g.jquery)?Ce(g):Ce.event,y=Ce.Deferred(),v=Ce.Callbacks("once memory"),x=h.statusCode||{},b={},w={},T="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!a)for(a={};t=Mt.exec(s);)a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return c?s:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||T;return i&&i.abort(t),r(0,t),this}};if(y.promise(E),h.url=((t||h.url||It.href)+"").replace(zt,It.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(Pe)||[""],null==h.crossDomain){l=we.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Yt.protocol+"//"+Yt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=Ce.param(h.data,h.traditional)),re(Vt,h,n,E),c)return E;f=Ce.event&&h.global,f&&0==Ce.active++&&Ce.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Wt.test(h.type),o=h.url.replace(_t,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace($t,"+")):(p=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(Pt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),p=(Pt.test(o)?"&":"?")+"_="+Ot.guid+++p),h.url=o+p),h.ifModified&&(Ce.lastModified[o]&&E.setRequestHeader("If-Modified-Since",Ce.lastModified[o]),Ce.etag[o]&&E.setRequestHeader("If-None-Match",Ce.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Xt+"; q=0.01":""):h.accepts["*"]);for(d in h.headers)E.setRequestHeader(d,h.headers[d]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(T="abort",v.add(h.complete),E.done(h.success),E.fail(h.error),i=re(Ut,h,n,E)){if(E.readyState=1,f&&m.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,r)}catch(e){if(c)throw e;r(-1,e)}}else r(-1,"No Transport");return E},getJSON:function(e,t,n){return Ce.get(e,t,n,"json")},getScript:function(e,t){return Ce.get(e,undefined,t,"script")}}),Ce.each(["get","post"],function(e,t){Ce[t]=function(e,n,r,i){return xe(n)&&(i=i||r,r=n,n=undefined),Ce.ajax(Ce.extend({url:e,type:t,dataType:i,data:n,success:r},Ce.isPlainObject(e)&&e))}}),Ce.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),Ce._evalUrl=function(e,t,n){return Ce.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){Ce.globalEval(e,t,n)}})},Ce.fn.extend({wrapAll:function(e){var t;return this[0]&&(xe(e)&&(e=e.call(this[0])),t=Ce(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return xe(e)?this.each(function(t){Ce(this).wrapInner(e.call(this,t))}):this.each(function(){var t=Ce(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=xe(e);return this.each(function(n){Ce(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){Ce(this).replaceWith(this.childNodes)}),this}}),Ce.expr.pseudos.hidden=function(e){return!Ce.expr.pseudos.visible(e)},Ce.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)}, +Ce.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Gt={0:200,1223:204},Jt=Ce.ajaxSettings.xhr();ve.cors=!!Jt&&"withCredentials"in Jt,ve.ajax=Jt=!!Jt,Ce.ajaxTransport(function(t){var n,r;if(ve.cors||Jt&&!t.crossDomain)return{send:function(i,o){var s,a=t.xhr();if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(s in t.xhrFields)a[s]=t.xhrFields[s];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(s in i)a.setRequestHeader(s,i[s]);n=function(e){return function(){n&&(n=r=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(Gt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=n(),r=a.onerror=a.ontimeout=n("error"),a.onabort!==undefined?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{a.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),Ce.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),Ce.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return Ce.globalEval(e),e}}}),Ce.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),Ce.ajaxTransport("script",function(e){if(e.crossDomain||e.scriptAttrs){var t,n;return{send:function(r,i){t=Ce(" - <% end %> - - - - - - NAV - <%= image_tag('navbar.png') %> - - -
    - <%= image_tag "logo.png", class: 'logo' %> - <% if language_tabs.any? %> -
    - <% language_tabs.each do |lang| %> - <% if lang.is_a? Hash %> - <%= lang.values.first %> - <% else %> - <%= lang %> - <% end %> - <% end %> -
    - <% end %> - <% if current_page.data.search %> - -
      - <% end %> -
        - <% toc_data(page_content).each do |h1| %> -
      • - <%= h1[:content] %> - <% if h1[:children].length > 0 %> - - <% end %> -
      • - <% end %> -
      - <% if current_page.data.toc_footers %> - - <% end %> -
      -
      -
      -
      - <%= page_content %> -
      -
      - <% if language_tabs.any? %> -
      - <% language_tabs.each do |lang| %> - <% if lang.is_a? Hash %> - <%= lang.values.first %> - <% else %> - <%= lang %> - <% end %> - <% end %> -
      - <% end %> -
      -
      - - diff --git a/slate-docs/source/stylesheets/_icon-font.scss b/slate-docs/source/stylesheets/_icon-font.scss deleted file mode 100644 index b5994839..00000000 --- a/slate-docs/source/stylesheets/_icon-font.scss +++ /dev/null @@ -1,38 +0,0 @@ -@font-face { - font-family: 'slate'; - src:font-url('slate.eot?-syv14m'); - src:font-url('slate.eot?#iefix-syv14m') format('embedded-opentype'), - font-url('slate.woff2?-syv14m') format('woff2'), - font-url('slate.woff?-syv14m') format('woff'), - font-url('slate.ttf?-syv14m') format('truetype'), - font-url('slate.svg?-syv14m#slate') format('svg'); - font-weight: normal; - font-style: normal; -} - -%icon { - font-family: 'slate'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; -} - -%icon-exclamation-sign { - @extend %icon; - content: "\e600"; -} -%icon-info-sign { - @extend %icon; - content: "\e602"; -} -%icon-ok-sign { - @extend %icon; - content: "\e606"; -} -%icon-search { - @extend %icon; - content: "\e607"; -} diff --git a/slate-docs/source/stylesheets/_normalize.scss b/slate-docs/source/stylesheets/_normalize.scss deleted file mode 100644 index 46f646a5..00000000 --- a/slate-docs/source/stylesheets/_normalize.scss +++ /dev/null @@ -1,427 +0,0 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ - -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ - -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ - -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ - -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ - -/** - * Remove the gray background color from active links in IE 10. - */ - -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ - -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Remove border when inside `a` element in IE 8/9/10. - */ - -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ - -/** - * Address margin not present in IE 8/9 and Safari. - */ - -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ - -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ - -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ - -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ - -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ - -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ - -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ - -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ - -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} diff --git a/slate-docs/source/stylesheets/_rtl.scss b/slate-docs/source/stylesheets/_rtl.scss deleted file mode 100644 index 720719a0..00000000 --- a/slate-docs/source/stylesheets/_rtl.scss +++ /dev/null @@ -1,140 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// RTL Styles Variables -//////////////////////////////////////////////////////////////////////////////// - -$default: auto; - -//////////////////////////////////////////////////////////////////////////////// -// TABLE OF CONTENTS -//////////////////////////////////////////////////////////////////////////////// - -#toc>ul>li>a>span { - float: left; -} - -.toc-wrapper { - transition: right 0.3s ease-in-out !important; - left: $default !important; - #{right}: 0; -} - -.toc-h2 { - padding-#{right}: $nav-padding + $nav-indent; -} - -#nav-button { - #{right}: 0; - transition: right 0.3s ease-in-out; - &.open { - right: $nav-width - } -} - -//////////////////////////////////////////////////////////////////////////////// -// PAGE LAYOUT AND CODE SAMPLE BACKGROUND -//////////////////////////////////////////////////////////////////////////////// -.page-wrapper { - margin-#{left}: $default !important; - margin-#{right}: $nav-width; - .dark-box { - #{right}: $default; - #{left}: 0; - } -} - -.lang-selector { - width: $default !important; - a { - float: right; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// CODE SAMPLE STYLES -//////////////////////////////////////////////////////////////////////////////// -.content { - &>h1, - &>h2, - &>h3, - &>h4, - &>h5, - &>h6, - &>p, - &>table, - &>ul, - &>ol, - &>aside, - &>dl { - margin-#{left}: $examples-width; - margin-#{right}: $default !important; - } - &>ul, - &>ol { - padding-#{right}: $main-padding + 15px; - } - table { - th, - td { - text-align: right; - } - } - dd { - margin-#{right}: 15px; - } - aside { - aside:before { - padding-#{left}: 0.5em; - } - .search-highlight { - background: linear-gradient(to top right, #F7E633 0%, #F1D32F 100%); - } - } - pre, - blockquote { - float: left !important; - clear: left !important; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// TYPOGRAPHY -//////////////////////////////////////////////////////////////////////////////// -h1, -h2, -h3, -h4, -h5, -h6, -p, -aside { - text-align: right; - direction: rtl; -} - -.toc-wrapper { - text-align: right; - direction: rtl; - font-weight: 100 !important; -} - - -//////////////////////////////////////////////////////////////////////////////// -// RESPONSIVE DESIGN -//////////////////////////////////////////////////////////////////////////////// -@media (max-width: $tablet-width) { - .toc-wrapper { - #{right}: -$nav-width; - &.open { - #{right}: 0; - } - } - .page-wrapper { - margin-#{right}: 0; - } -} - -@media (max-width: $phone-width) { - %left-col { - margin-#{left}: 0; - } -} diff --git a/slate-docs/source/stylesheets/_variables.scss b/slate-docs/source/stylesheets/_variables.scss deleted file mode 100644 index 00bc0b35..00000000 --- a/slate-docs/source/stylesheets/_variables.scss +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2008-2013 Concur Technologies, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); you may -not use this file except in compliance with the License. You may obtain -a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -License for the specific language governing permissions and limitations -under the License. -*/ - - -//////////////////////////////////////////////////////////////////////////////// -// CUSTOMIZE SLATE -//////////////////////////////////////////////////////////////////////////////// -// Use these settings to help adjust the appearance of Slate - - -// BACKGROUND COLORS -//////////////////// -$nav-bg: #2E3336 !default; -$examples-bg: #2E3336 !default; -$code-bg: #1E2224 !default; -$code-annotation-bg: #191D1F !default; -$nav-subitem-bg: #1E2224 !default; -$nav-active-bg: #0F75D4 !default; -$nav-active-parent-bg: #1E2224 !default; // parent links of the current section -$lang-select-border: #000 !default; -$lang-select-bg: #1E2224 !default; -$lang-select-active-bg: $examples-bg !default; // feel free to change this to blue or something -$lang-select-pressed-bg: #111 !default; // color of language tab bg when mouse is pressed -$main-bg: #F3F7F9 !default; -$aside-notice-bg: #8fbcd4 !default; -$aside-warning-bg: #ffe082 !default; // using yellow instead of standard red for warnings -$aside-success-bg: #6ac174 !default; -$search-notice-bg: #c97a7e !default; - - -// TEXT COLORS -//////////////////// -$main-text: #333 !default; // main content text color -$nav-text: #fff !default; -$nav-active-text: #fff !default; -$nav-active-parent-text: #fff !default; // parent links of the current section -$lang-select-text: #fff !default; // color of unselected language tab text -$lang-select-active-text: #fff !default; // color of selected language tab text -$lang-select-pressed-text: #fff !default; // color of language tab text when mouse is pressed - - -// SIZES -//////////////////// -$nav-width: 230px !default; // width of the navbar -$examples-width: 50% !default; // portion of the screen taken up by code examples -$logo-margin: 0px !default; // margin below logo -$main-padding: 28px !default; // padding to left and right of content & examples -$nav-padding: 15px !default; // padding to left and right of navbar -$nav-v-padding: 10px !default; // padding used vertically around search boxes and results -$nav-indent: 10px !default; // extra padding for ToC subitems -$code-annotation-padding: 13px !default; // padding inside code annotations -$h1-margin-bottom: 21px !default; // padding under the largest header tags -$tablet-width: 930px !default; // min width before reverting to tablet size -$phone-width: $tablet-width - $nav-width !default; // min width before reverting to mobile size - - -// FONTS -//////////////////// -%default-font { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 14px; -} - -%header-font { - @extend %default-font; - font-weight: bold; -} - -%code-font { - font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif; - font-size: 12px; - line-height: 1.5; -} - - -// OTHER -//////////////////// -$nav-footer-border-color: #666 !default; -$search-box-border-color: #666 !default; - - -//////////////////////////////////////////////////////////////////////////////// -// INTERNAL -//////////////////////////////////////////////////////////////////////////////// -// These settings are probably best left alone. - -%break-words { - word-break: break-all; - hyphens: auto; -} diff --git a/slate-docs/source/stylesheets/print.css.scss b/slate-docs/source/stylesheets/print.css.scss deleted file mode 100644 index aea88c30..00000000 --- a/slate-docs/source/stylesheets/print.css.scss +++ /dev/null @@ -1,153 +0,0 @@ -@charset "utf-8"; -@import 'normalize'; -@import 'variables'; -@import 'icon-font'; - -/* -Copyright 2008-2013 Concur Technologies, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); you may -not use this file except in compliance with the License. You may obtain -a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -License for the specific language governing permissions and limitations -under the License. -*/ - -$print-color: #999; -$print-color-light: #ccc; -$print-font-size: 12px; - -body { - @extend %default-font; -} - -.tocify, .toc-footer, .lang-selector, .search, #nav-button { - display: none; -} - -.tocify-wrapper>img { - margin: 0 auto; - display: block; -} - -.content { - font-size: 12px; - - pre, code { - @extend %code-font; - @extend %break-words; - border: 1px solid $print-color; - border-radius: 5px; - font-size: 0.8em; - } - - pre { - code { - border: 0; - } - } - - pre { - padding: 1.3em; - } - - code { - padding: 0.2em; - } - - table { - border: 1px solid $print-color; - tr { - border-bottom: 1px solid $print-color; - } - td,th { - padding: 0.7em; - } - } - - p { - line-height: 1.5; - } - - a { - text-decoration: none; - color: #000; - } - - h1 { - @extend %header-font; - font-size: 2.5em; - padding-top: 0.5em; - padding-bottom: 0.5em; - margin-top: 1em; - margin-bottom: $h1-margin-bottom; - border: 2px solid $print-color-light; - border-width: 2px 0; - text-align: center; - } - - h2 { - @extend %header-font; - font-size: 1.8em; - margin-top: 2em; - border-top: 2px solid $print-color-light; - padding-top: 0.8em; - } - - h1+h2, h1+div+h2 { - border-top: none; - padding-top: 0; - margin-top: 0; - } - - h3, h4 { - @extend %header-font; - font-size: 0.8em; - margin-top: 1.5em; - margin-bottom: 0.8em; - text-transform: uppercase; - } - - h5, h6 { - text-transform: uppercase; - } - - aside { - padding: 1em; - border: 1px solid $print-color-light; - border-radius: 5px; - margin-top: 1.5em; - margin-bottom: 1.5em; - line-height: 1.6; - } - - aside:before { - vertical-align: middle; - padding-right: 0.5em; - font-size: 14px; - } - - aside.notice:before { - @extend %icon-info-sign; - } - - aside.warning:before { - @extend %icon-exclamation-sign; - } - - aside.success:before { - @extend %icon-ok-sign; - } -} - -.copy-clipboard { - @media print { - display: none - } -} diff --git a/slate-docs/source/stylesheets/screen.css.scss b/slate-docs/source/stylesheets/screen.css.scss deleted file mode 100644 index 70e3527d..00000000 --- a/slate-docs/source/stylesheets/screen.css.scss +++ /dev/null @@ -1,633 +0,0 @@ -@charset "utf-8"; -@import 'normalize'; -@import 'variables'; -@import 'icon-font'; -// @import 'rtl'; // uncomment to switch to RTL format - -/* -Copyright 2008-2013 Concur Technologies, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); you may -not use this file except in compliance with the License. You may obtain -a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -License for the specific language governing permissions and limitations -under the License. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// GENERAL STUFF -//////////////////////////////////////////////////////////////////////////////// - -html, body { - color: $main-text; - padding: 0; - margin: 0; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - @extend %default-font; - background-color: $main-bg; - height: 100%; - -webkit-text-size-adjust: none; /* Never autoresize text */ -} - -//////////////////////////////////////////////////////////////////////////////// -// TABLE OF CONTENTS -//////////////////////////////////////////////////////////////////////////////// - -#toc > ul > li > a > span { - float: right; - background-color: #2484FF; - border-radius: 40px; - width: 20px; -} - -.toc-wrapper { - transition: left 0.3s ease-in-out; - - overflow-y: auto; - overflow-x: hidden; - position: fixed; - z-index: 30; - top: 0; - left: 0; - bottom: 0; - width: $nav-width; - background-color: $nav-bg; - font-size: 13px; - font-weight: bold; - - // language selector for mobile devices - .lang-selector { - display: none; - a { - padding-top: 0.5em; - padding-bottom: 0.5em; - } - } - - // This is the logo at the top of the ToC - .logo { - display: block; - max-width: 100%; - margin-bottom: $logo-margin; - } - - &>.search { - position: relative; - - input { - background: $nav-bg; - border-width: 0 0 1px 0; - border-color: $search-box-border-color; - padding: 6px 0 6px 20px; - box-sizing: border-box; - margin: $nav-v-padding $nav-padding; - width: $nav-width - ($nav-padding*2); - outline: none; - color: $nav-text; - border-radius: 0; /* ios has a default border radius */ - } - - &:before { - position: absolute; - top: 17px; - left: $nav-padding; - color: $nav-text; - @extend %icon-search; - } - } - - .search-results { - margin-top: 0; - box-sizing: border-box; - height: 0; - overflow-y: auto; - overflow-x: hidden; - transition-property: height, margin; - transition-duration: 180ms; - transition-timing-function: ease-in-out; - background: $nav-subitem-bg; - &.visible { - height: 30%; - margin-bottom: 1em; - } - - li { - margin: 1em $nav-padding; - line-height: 1; - } - - a { - color: $nav-text; - text-decoration: none; - - &:hover { - text-decoration: underline; - } - } - } - - - // The Table of Contents is composed of multiple nested - // unordered lists. These styles remove the default - // styling of an unordered list because it is ugly. - ul, li { - list-style: none; - margin: 0; - padding: 0; - line-height: 28px; - } - - li { - color: $nav-text; - transition-property: background; - transition-timing-function: linear; - transition-duration: 200ms; - } - - // This is the currently selected ToC entry - .toc-link.active { - background-color: $nav-active-bg; - color: $nav-active-text; - } - - // this is parent links of the currently selected ToC entry - .toc-link.active-parent { - background-color: $nav-active-parent-bg; - color: $nav-active-parent-text; - } - - .toc-list-h2 { - display: none; - background-color: $nav-subitem-bg; - font-weight: 500; - } - - .toc-h2 { - padding-left: $nav-padding + $nav-indent; - font-size: 12px; - } - - .toc-footer { - padding: 1em 0; - margin-top: 1em; - border-top: 1px dashed $nav-footer-border-color; - - li,a { - color: $nav-text; - text-decoration: none; - } - - a:hover { - text-decoration: underline; - } - - li { - font-size: 0.8em; - line-height: 1.7; - text-decoration: none; - } - } -} - -.toc-link, .toc-footer li { - padding: 0 $nav-padding 0 $nav-padding; - display: block; - overflow-x: hidden; - white-space: nowrap; - text-overflow: ellipsis; - text-decoration: none; - color: $nav-text; - transition-property: background; - transition-timing-function: linear; - transition-duration: 130ms; -} - -// button to show navigation on mobile devices -#nav-button { - span { - display: block; - $side-pad: $main-padding / 2 - 8px; - padding: $side-pad $side-pad $side-pad; - background-color: rgba($main-bg, 0.7); - transform-origin: 0 0; - transform: rotate(-90deg) translate(-100%, 0); - border-radius: 0 0 0 5px; - } - padding: 0 1.5em 5em 0; // increase touch size area - display: none; - position: fixed; - top: 0; - left: 0; - z-index: 100; - color: #000; - text-decoration: none; - font-weight: bold; - opacity: 0.7; - line-height: 16px; - img { - height: 16px; - vertical-align: bottom; - } - - transition: left 0.3s ease-in-out; - - &:hover { opacity: 1; } - &.open {left: $nav-width} -} - - -//////////////////////////////////////////////////////////////////////////////// -// PAGE LAYOUT AND CODE SAMPLE BACKGROUND -//////////////////////////////////////////////////////////////////////////////// - -.page-wrapper { - margin-left: $nav-width; - position: relative; - z-index: 10; - background-color: $main-bg; - min-height: 100%; - - padding-bottom: 1px; // prevent margin overflow - - // The dark box is what gives the code samples their dark background. - // It sits essentially under the actual content block, which has a - // transparent background. - // I know, it's hackish, but it's the simplist way to make the left - // half of the content always this background color. - .dark-box { - width: $examples-width; - background-color: $examples-bg; - position: absolute; - right: 0; - top: 0; - bottom: 0; - } - - .lang-selector { - position: fixed; - z-index: 50; - border-bottom: 5px solid $lang-select-active-bg; - } -} - -.lang-selector { - display: flex; - background-color: $lang-select-bg; - width: 100%; - font-weight: bold; - overflow-x: auto; - a { - display: inline; - color: $lang-select-text; - text-decoration: none; - padding: 0 10px; - line-height: 30px; - outline: 0; - - &:active, &:focus { - background-color: $lang-select-pressed-bg; - color: $lang-select-pressed-text; - } - - &.active { - background-color: $lang-select-active-bg; - color: $lang-select-active-text; - } - } - - &:after { - content: ''; - clear: both; - display: block; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// CONTENT STYLES -//////////////////////////////////////////////////////////////////////////////// -// This is all the stuff with the light background in the left half of the page - -.content { - // fixes webkit rendering bug for some: see #538 - -webkit-transform: translateZ(0); - // to place content above the dark box - position: relative; - z-index: 30; - - &:after { - content: ''; - display: block; - clear: both; - } - - &>h1, &>h2, &>h3, &>h4, &>h5, &>h6, &>p, &>table, &>ul, &>ol, &>aside, &>dl { - margin-right: $examples-width; - padding: 0 $main-padding; - box-sizing: border-box; - display: block; - - @extend %left-col; - } - - &>ul, &>ol { - padding-left: $main-padding + 15px; - } - - // the div is the tocify hidden div for placeholding stuff - &>h1, &>h2, &>div { - clear:both; - } - - h1 { - @extend %header-font; - font-size: 25px; - padding-top: 0.5em; - padding-bottom: 0.5em; - margin-bottom: $h1-margin-bottom; - margin-top: 2em; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; - background-color: #fdfdfd; - } - - h1:first-child, div:first-child + h1 { - border-top-width: 0; - margin-top: 0; - } - - h2 { - @extend %header-font; - font-size: 19px; - margin-top: 4em; - margin-bottom: 0; - border-top: 1px solid #ccc; - padding-top: 1.2em; - padding-bottom: 1.2em; - background-image: linear-gradient(to bottom, rgba(#fff, 0.2), rgba(#fff, 0)); - } - - // h2s right after h1s should bump right up - // against the h1s. - h1 + h2, h1 + div + h2 { - margin-top: $h1-margin-bottom * -1; - border-top: none; - } - - h3, h4, h5, h6 { - @extend %header-font; - font-size: 15px; - margin-top: 2.5em; - margin-bottom: 0.8em; - } - - h4, h5, h6 { - font-size: 10px; - } - - hr { - margin: 2em 0; - border-top: 2px solid $examples-bg; - border-bottom: 2px solid $main-bg; - } - - table { - margin-bottom: 1em; - overflow: auto; - th,td { - text-align: left; - vertical-align: top; - line-height: 1.6; - code { - white-space: nowrap; - } - } - - th { - padding: 5px 10px; - border-bottom: 1px solid #ccc; - vertical-align: bottom; - } - - td { - padding: 10px; - } - - tr:last-child { - border-bottom: 1px solid #ccc; - } - - tr:nth-child(odd)>td { - background-color: lighten($main-bg,4.2%); - } - - tr:nth-child(even)>td { - background-color: lighten($main-bg,2.4%); - } - } - - dt { - font-weight: bold; - } - - dd { - margin-left: 15px; - } - - p, li, dt, dd { - line-height: 1.6; - margin-top: 0; - } - - img { - max-width: 100%; - } - - code { - background-color: rgba(0,0,0,0.05); - padding: 3px; - border-radius: 3px; - @extend %break-words; - @extend %code-font; - } - - pre>code { - background-color: transparent; - padding: 0; - } - - aside { - padding-top: 1em; - padding-bottom: 1em; - margin-top: 1.5em; - margin-bottom: 1.5em; - background: $aside-notice-bg; - line-height: 1.6; - - &.warning { - background-color: $aside-warning-bg; - } - - &.success { - background-color: $aside-success-bg; - } - } - - aside:before { - vertical-align: middle; - padding-right: 0.5em; - font-size: 14px; - } - - aside.notice:before { - @extend %icon-info-sign; - } - - aside.warning:before { - @extend %icon-exclamation-sign; - } - - aside.success:before { - @extend %icon-ok-sign; - } - - .search-highlight { - padding: 2px; - margin: -3px; - border-radius: 4px; - border: 1px solid #F7E633; - background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// CODE SAMPLE STYLES -//////////////////////////////////////////////////////////////////////////////// -// This is all the stuff that appears in the right half of the page - -.content { - &>div.highlight { - clear:none; - } - - pre, blockquote { - background-color: $code-bg; - color: #fff; - - margin: 0; - width: $examples-width; - - float:right; - clear:right; - - box-sizing: border-box; - - @extend %right-col; - - &>p { margin: 0; } - - a { - color: #fff; - text-decoration: none; - border-bottom: dashed 1px #ccc; - } - } - - pre { - @extend %code-font; - padding-top: 2em; - padding-bottom: 2em; - padding: 2em $main-padding; - } - - blockquote { - &>p { - background-color: $code-annotation-bg; - padding: $code-annotation-padding 2em; - color: #eee; - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// RESPONSIVE DESIGN -//////////////////////////////////////////////////////////////////////////////// -// These are the styles for phones and tablets -// There are also a couple styles disperesed - -@media (max-width: $tablet-width) { - .toc-wrapper { - left: -$nav-width; - - &.open { - left: 0; - } - } - - .page-wrapper { - margin-left: 0; - } - - #nav-button { - display: block; - } - - .toc-link { - padding-top: 0.3em; - padding-bottom: 0.3em; - } -} - -@media (max-width: $phone-width) { - .dark-box { - display: none; - } - - %left-col { - margin-right: 0; - } - - .toc-wrapper .lang-selector { - display: block; - } - - .page-wrapper .lang-selector { - display: none; - } - - %right-col { - width: auto; - float: none; - } - - %right-col + %left-col { - margin-top: $main-padding; - } -} - -.highlight .c, .highlight .cm, .highlight .c1, .highlight .cs { - color: #909090; -} - -.highlight, .highlight .w { - background-color: $code-bg; -} - -.copy-clipboard { - float: right; - fill: #9DAAB6; - cursor: pointer; - opacity: 0.4; - height: 18px; - width: 18px; -} - -.copy-clipboard:hover { - opacity: 0.8; -} diff --git a/stylesheets/print-953e3353.css b/stylesheets/print-953e3353.css new file mode 100644 index 00000000..9a0ec9e6 --- /dev/null +++ b/stylesheets/print-953e3353.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.content h1,.content h2,.content h3,.content h4,body{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-size:14px}.content h1,.content h2,.content h3,.content h4{font-weight:bold}.content pre,.content code{font-family:Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif;font-size:12px;line-height:1.5}.content pre,.content code{word-break:break-all;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}@font-face{font-family:'slate';src:url(../fonts/slate-cfc9d06b.eot?-syv14m);src:url(../fonts/slate-cfc9d06b.eot?#iefix-syv14m) format("embedded-opentype"),url(../fonts/slate.woff2?-syv14m) format("woff2"),url(../fonts/slate.woff?-syv14m) format("woff"),url(../fonts/slate-7b7da4fe.ttf?-syv14m) format("truetype"),url(../fonts/slate-e55b8307.svg?-syv14m#slate) format("svg");font-weight:normal;font-style:normal}.content aside.warning:before,.content aside.notice:before,.content aside.success:before{font-family:'slate';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1}.content aside.warning:before{content:"\e600"}.content aside.notice:before{content:"\e602"}.content aside.success:before{content:"\e606"}.tocify,.toc-footer,.lang-selector,.search,#nav-button{display:none}.tocify-wrapper>img{margin:0 auto;display:block}.content{font-size:12px}.content pre,.content code{border:1px solid #999;border-radius:5px;font-size:0.8em}.content pre code{border:0}.content pre{padding:1.3em}.content code{padding:0.2em}.content table{border:1px solid #999}.content table tr{border-bottom:1px solid #999}.content table td,.content table th{padding:0.7em}.content p{line-height:1.5}.content a{text-decoration:none;color:#000}.content h1{font-size:2.5em;padding-top:0.5em;padding-bottom:0.5em;margin-top:1em;margin-bottom:21px;border:2px solid #ccc;border-width:2px 0;text-align:center}.content h2{font-size:1.8em;margin-top:2em;border-top:2px solid #ccc;padding-top:0.8em}.content h1+h2,.content h1+div+h2{border-top:none;padding-top:0;margin-top:0}.content h3,.content h4{font-size:0.8em;margin-top:1.5em;margin-bottom:0.8em;text-transform:uppercase}.content h5,.content h6{text-transform:uppercase}.content aside{padding:1em;border:1px solid #ccc;border-radius:5px;margin-top:1.5em;margin-bottom:1.5em;line-height:1.6}.content aside:before{vertical-align:middle;padding-right:0.5em;font-size:14px}@media print{.copy-clipboard{display:none}} \ No newline at end of file diff --git a/stylesheets/screen-befc07b5.css b/stylesheets/screen-befc07b5.css new file mode 100644 index 00000000..aaf28af4 --- /dev/null +++ b/stylesheets/screen-befc07b5.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6,html,body{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-size:14px}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{font-weight:bold}.content code,.content pre{font-family:Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif;font-size:12px;line-height:1.5}.content code{word-break:break-all;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}@font-face{font-family:'slate';src:url(../fonts/slate-cfc9d06b.eot?-syv14m);src:url(../fonts/slate-cfc9d06b.eot?#iefix-syv14m) format("embedded-opentype"),url(../fonts/slate.woff2?-syv14m) format("woff2"),url(../fonts/slate.woff?-syv14m) format("woff"),url(../fonts/slate-7b7da4fe.ttf?-syv14m) format("truetype"),url(../fonts/slate-e55b8307.svg?-syv14m#slate) format("svg");font-weight:normal;font-style:normal}.content aside.warning:before,.content aside.notice:before,.content aside.success:before,.toc-wrapper>.search:before{font-family:'slate';speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1}.content aside.warning:before{content:"\e600"}.content aside.notice:before{content:"\e602"}.content aside.success:before{content:"\e606"}.toc-wrapper>.search:before{content:"\e607"}html,body{color:#333;padding:0;margin:0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#F3F7F9;height:100%;-webkit-text-size-adjust:none}#toc>ul>li>a>span{float:right;background-color:#2484FF;border-radius:40px;width:20px}.toc-wrapper{-webkit-transition:left 0.3s ease-in-out;transition:left 0.3s ease-in-out;overflow-y:auto;overflow-x:hidden;position:fixed;z-index:30;top:0;left:0;bottom:0;width:230px;background-color:#2E3336;font-size:13px;font-weight:bold}.toc-wrapper .lang-selector{display:none}.toc-wrapper .lang-selector a{padding-top:0.5em;padding-bottom:0.5em}.toc-wrapper .logo{display:block;max-width:100%;margin-bottom:0px}.toc-wrapper>.search{position:relative}.toc-wrapper>.search input{background:#2E3336;border-width:0 0 1px 0;border-color:#666;padding:6px 0 6px 20px;-webkit-box-sizing:border-box;box-sizing:border-box;margin:10px 15px;width:200px;outline:none;color:#fff;border-radius:0}.toc-wrapper>.search:before{position:absolute;top:17px;left:15px;color:#fff}.toc-wrapper .search-results{margin-top:0;-webkit-box-sizing:border-box;box-sizing:border-box;height:0;overflow-y:auto;overflow-x:hidden;-webkit-transition-property:height, margin;transition-property:height, margin;-webkit-transition-duration:180ms;transition-duration:180ms;-webkit-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out;background:#1E2224}.toc-wrapper .search-results.visible{height:30%;margin-bottom:1em}.toc-wrapper .search-results li{margin:1em 15px;line-height:1}.toc-wrapper .search-results a{color:#fff;text-decoration:none}.toc-wrapper .search-results a:hover{text-decoration:underline}.toc-wrapper ul,.toc-wrapper li{list-style:none;margin:0;padding:0;line-height:28px}.toc-wrapper li{color:#fff;-webkit-transition-property:background;transition-property:background;-webkit-transition-timing-function:linear;transition-timing-function:linear;-webkit-transition-duration:200ms;transition-duration:200ms}.toc-wrapper .toc-link.active{background-color:#0F75D4;color:#fff}.toc-wrapper .toc-link.active-parent{background-color:#1E2224;color:#fff}.toc-wrapper .toc-list-h2{display:none;background-color:#1E2224;font-weight:500}.toc-wrapper .toc-h2{padding-left:25px;font-size:12px}.toc-wrapper .toc-footer{padding:1em 0;margin-top:1em;border-top:1px dashed #666}.toc-wrapper .toc-footer li,.toc-wrapper .toc-footer a{color:#fff;text-decoration:none}.toc-wrapper .toc-footer a:hover{text-decoration:underline}.toc-wrapper .toc-footer li{font-size:0.8em;line-height:1.7;text-decoration:none}.toc-link,.toc-footer li{padding:0 15px 0 15px;display:block;overflow-x:hidden;white-space:nowrap;text-overflow:ellipsis;text-decoration:none;color:#fff;-webkit-transition-property:background;transition-property:background;-webkit-transition-timing-function:linear;transition-timing-function:linear;-webkit-transition-duration:130ms;transition-duration:130ms}#nav-button{padding:0 1.5em 5em 0;display:none;position:fixed;top:0;left:0;z-index:100;color:#000;text-decoration:none;font-weight:bold;opacity:0.7;line-height:16px;-webkit-transition:left 0.3s ease-in-out;transition:left 0.3s ease-in-out}#nav-button span{display:block;padding:6px 6px 6px;background-color:rgba(243,247,249,0.7);-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:rotate(-90deg) translate(-100%, 0);transform:rotate(-90deg) translate(-100%, 0);border-radius:0 0 0 5px}#nav-button img{height:16px;vertical-align:bottom}#nav-button:hover{opacity:1}#nav-button.open{left:230px}.page-wrapper{margin-left:230px;position:relative;z-index:10;background-color:#F3F7F9;min-height:100%;padding-bottom:1px}.page-wrapper .dark-box{width:50%;background-color:#2E3336;position:absolute;right:0;top:0;bottom:0}.page-wrapper .lang-selector{position:fixed;z-index:50;border-bottom:5px solid #2E3336}.lang-selector{display:flex;background-color:#1E2224;width:100%;font-weight:bold;overflow-x:auto}.lang-selector a{display:inline;color:#fff;text-decoration:none;padding:0 10px;line-height:30px;outline:0}.lang-selector a:active,.lang-selector a:focus{background-color:#111;color:#fff}.lang-selector a.active{background-color:#2E3336;color:#fff}.lang-selector:after{content:'';clear:both;display:block}.content{-webkit-transform:translateZ(0);position:relative;z-index:30}.content:after{content:'';display:block;clear:both}.content>h1,.content>h2,.content>h3,.content>h4,.content>h5,.content>h6,.content>p,.content>table,.content>ul,.content>ol,.content>aside,.content>dl{margin-right:50%;padding:0 28px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block}.content>ul,.content>ol{padding-left:43px}.content>h1,.content>h2,.content>div{clear:both}.content h1{font-size:25px;padding-top:0.5em;padding-bottom:0.5em;margin-bottom:21px;margin-top:2em;border-top:1px solid #ccc;border-bottom:1px solid #ccc;background-color:#fdfdfd}.content h1:first-child,.content div:first-child+h1{border-top-width:0;margin-top:0}.content h2{font-size:19px;margin-top:4em;margin-bottom:0;border-top:1px solid #ccc;padding-top:1.2em;padding-bottom:1.2em;background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,0.2)), to(rgba(255,255,255,0)));background-image:linear-gradient(to bottom, rgba(255,255,255,0.2), rgba(255,255,255,0))}.content h1+h2,.content h1+div+h2{margin-top:-21px;border-top:none}.content h3,.content h4,.content h5,.content h6{font-size:15px;margin-top:2.5em;margin-bottom:0.8em}.content h4,.content h5,.content h6{font-size:10px}.content hr{margin:2em 0;border-top:2px solid #2E3336;border-bottom:2px solid #F3F7F9}.content table{margin-bottom:1em;overflow:auto}.content table th,.content table td{text-align:left;vertical-align:top;line-height:1.6}.content table th code,.content table td code{white-space:nowrap}.content table th{padding:5px 10px;border-bottom:1px solid #ccc;vertical-align:bottom}.content table td{padding:10px}.content table tr:last-child{border-bottom:1px solid #ccc}.content table tr:nth-child(odd)>td{background-color:white}.content table tr:nth-child(even)>td{background-color:#fbfcfd}.content dt{font-weight:bold}.content dd{margin-left:15px}.content p,.content li,.content dt,.content dd{line-height:1.6;margin-top:0}.content img{max-width:100%}.content code{background-color:rgba(0,0,0,0.05);padding:3px;border-radius:3px}.content pre>code{background-color:transparent;padding:0}.content aside{padding-top:1em;padding-bottom:1em;margin-top:1.5em;margin-bottom:1.5em;background:#8fbcd4;line-height:1.6}.content aside.warning{background-color:#ffe082}.content aside.success{background-color:#6ac174}.content aside:before{vertical-align:middle;padding-right:0.5em;font-size:14px}.content .search-highlight{padding:2px;margin:-3px;border-radius:4px;border:1px solid #F7E633;background:-webkit-gradient(linear, right bottom, left top, from(#F7E633), to(#F1D32F));background:linear-gradient(to top left, #F7E633 0%, #F1D32F 100%)}.content>div.highlight{clear:none}.content pre,.content blockquote{background-color:#1E2224;color:#fff;margin:0;width:50%;float:right;clear:right;-webkit-box-sizing:border-box;box-sizing:border-box}.content pre>p,.content blockquote>p{margin:0}.content pre a,.content blockquote a{color:#fff;text-decoration:none;border-bottom:dashed 1px #ccc}.content pre{padding-top:2em;padding-bottom:2em;padding:2em 28px}.content blockquote>p{background-color:#191D1F;padding:13px 2em;color:#eee}@media (max-width: 930px){.toc-wrapper{left:-230px}.toc-wrapper.open{left:0}.page-wrapper{margin-left:0}#nav-button{display:block}.toc-link{padding-top:0.3em;padding-bottom:0.3em}}@media (max-width: 700px){.dark-box{display:none}.content>h1,.content>h2,.content>h3,.content>h4,.content>h5,.content>h6,.content>p,.content>table,.content>ul,.content>ol,.content>aside,.content>dl{margin-right:0}.toc-wrapper .lang-selector{display:block}.page-wrapper .lang-selector{display:none}.content pre,.content blockquote{width:auto;float:none}.content>pre+h1,.content>blockquote+h1,.content>pre+h2,.content>blockquote+h2,.content>pre+h3,.content>blockquote+h3,.content>pre+h4,.content>blockquote+h4,.content>pre+h5,.content>blockquote+h5,.content>pre+h6,.content>blockquote+h6,.content>pre+p,.content>blockquote+p,.content>pre+table,.content>blockquote+table,.content>pre+ul,.content>blockquote+ul,.content>pre+ol,.content>blockquote+ol,.content>pre+aside,.content>blockquote+aside,.content>pre+dl,.content>blockquote+dl{margin-top:28px}}.highlight .c,.highlight .cm,.highlight .c1,.highlight .cs{color:#909090}.highlight,.highlight .w{background-color:#1E2224}.copy-clipboard{float:right;fill:#9DAAB6;cursor:pointer;opacity:0.4;height:18px;width:18px}.copy-clipboard:hover{opacity:0.8} \ No newline at end of file