From 842cc9e379efb9e8686ecac327c0ea2d79cf290f Mon Sep 17 00:00:00 2001 From: MiSikora Date: Mon, 2 Dec 2024 07:31:51 +0000 Subject: [PATCH] Deployed c090de6 with MkDocs version: 1.4.2 --- .nojekyll | 0 404.html | 378 + api/images/anchor-copy-button.svg | 8 + api/images/arrow_down.svg | 7 + api/images/burger.svg | 9 + api/images/copy-icon.svg | 7 + api/images/copy-successful-icon.svg | 7 + api/images/footer-go-to-link.svg | 7 + api/images/go-to-top-icon.svg | 8 + api/images/homepage.svg | 3 + api/images/logo-icon.svg | 14 + .../nav-icons/abstract-class-kotlin.svg | 26 + api/images/nav-icons/abstract-class.svg | 20 + api/images/nav-icons/annotation-kotlin.svg | 13 + api/images/nav-icons/annotation.svg | 7 + api/images/nav-icons/class-kotlin.svg | 13 + api/images/nav-icons/class.svg | 7 + api/images/nav-icons/enum-kotlin.svg | 13 + api/images/nav-icons/enum.svg | 7 + api/images/nav-icons/exception-class.svg | 7 + api/images/nav-icons/field-value.svg | 10 + api/images/nav-icons/field-variable.svg | 10 + api/images/nav-icons/function.svg | 7 + api/images/nav-icons/interface-kotlin.svg | 13 + api/images/nav-icons/interface.svg | 7 + api/images/nav-icons/object.svg | 13 + api/images/nav-icons/typealias-kotlin.svg | 13 + api/images/theme-toggle.svg | 7 + api/index.html | 142 + api/laboratory/data-store/index.html | 95 + .../default-value.html | 76 + .../-feature-flags-serializer/index.html | 134 + .../-feature-flags-serializer/read-from.html | 76 + .../-feature-flags-serializer/write-to.html | 76 + .../data-store.html | 76 + .../io.mehow.laboratory.datastore/index.html | 118 + api/laboratory/data-store/navigation.html | 412 + api/laboratory/generator/index.html | 95 + .../-deprecation/-deprecation.html | 76 + .../-deprecation/index.html | 134 + .../-deprecation/level.html | 76 + .../-deprecation/message.html | 76 + .../-feature-factory-model.html | 76 + .../-feature-factory-model/class-name.html | 76 + .../-feature-factory-model/features.html | 76 + .../-feature-factory-model/index.html | 168 + .../-feature-factory-model/prepare.html | 76 + .../-feature-factory-model/visibility.html | 76 + .../-feature-flag-model.html | 76 + .../-feature-flag-model/class-name.html | 76 + .../-feature-flag-model/deprecation.html | 76 + .../-feature-flag-model/description.html | 76 + .../-feature-flag-model/equals.html | 76 + .../-feature-flag-model/hash-code.html | 76 + .../-feature-flag-model/index.html | 288 + .../-feature-flag-model/key.html | 76 + .../-feature-flag-model/options.html | 76 + .../-feature-flag-model/prepare.html | 76 + .../-feature-flag-model/source.html | 76 + .../-feature-flag-model/supervisor.html | 76 + .../-feature-flag-model/to-string.html | 76 + .../-feature-flag-model/visibility.html | 76 + .../-feature-flag-option.html | 76 + .../-feature-flag-option/index.html | 134 + .../-feature-flag-option/is-default.html | 76 + .../-feature-flag-option/name.html | 76 + .../-option-factory-model.html | 76 + .../-option-factory-model/class-name.html | 76 + .../-option-factory-model/features.html | 76 + .../-option-factory-model/index.html | 168 + .../-option-factory-model/prepare.html | 76 + .../-option-factory-model/visibility.html | 76 + .../-sourced-feature-storage-model.html | 76 + .../class-name.html | 76 + .../-sourced-feature-storage-model/index.html | 168 + .../prepare.html | 76 + .../source-names.html | 76 + .../visibility.html | 76 + .../-supervisor/-supervisor.html | 76 + .../-supervisor/feature-flag.html | 76 + .../-supervisor/index.html | 134 + .../-supervisor/option.html | 76 + .../-visibility/-internal/index.html | 115 + .../-visibility/-public/index.html | 115 + .../-visibility/entries.html | 76 + .../-visibility/index.html | 198 + .../-visibility/value-of.html | 76 + .../-visibility/values.html | 76 + .../io.mehow.laboratory.generator/index.html | 204 + api/laboratory/generator/navigation.html | 412 + api/laboratory/gradle-plugin/index.html | 95 + .../disabled-feature.html | 76 + .../enabled-feature.html | 76 + .../-child-feature-flags-input/feature.html | 76 + .../-child-feature-flags-input/index.html | 130 + .../-feature-factory/index.html | 115 + .../-feature-source-factory/index.html | 115 + .../-option-factory/index.html | 115 + .../-sourced-storage/index.html | 115 + .../-dependency-contribution/entries.html | 76 + .../-dependency-contribution/index.html | 228 + .../-dependency-contribution/value-of.html | 76 + .../-dependency-contribution/values.html | 76 + .../-deprecation-level/-error/index.html | 115 + .../-deprecation-level/-hidden/index.html | 115 + .../-deprecation-level/-warning/index.html | 115 + .../-deprecation-level/entries.html | 76 + .../-deprecation-level/index.html | 213 + .../-deprecation-level/value-of.html | 76 + .../-deprecation-level/values.html | 76 + .../-feature-factory-input/index.html | 115 + .../-feature-factory-input/is-public.html | 76 + .../-feature-factory-input/package-name.html | 76 + .../-binary-option/description.html | 76 + .../-binary-option/index.html | 224 + .../-binary-option/is-public.html | 76 + .../-binary-option/key.html | 76 + .../-binary-option/with-disabled.html | 76 + .../-binary-option/with-enabled.html | 76 + .../-multi-option/description.html | 76 + .../-multi-option/index.html | 224 + .../-multi-option/is-public.html | 76 + .../-multi-option/key.html | 76 + .../-multi-option/with-default-option.html | 76 + .../-multi-option/with-option.html | 76 + .../-feature-flag-input/deprecated.html | 76 + .../-feature-flag-input/description.html | 76 + .../-feature-flag-input/index.html | 228 + .../-feature-flag-input/is-public.html | 76 + .../-feature-flag-input/key.html | 76 + .../-feature-flag-input/package-name.html | 76 + .../with-default-source.html | 76 + .../-feature-flag-input/with-source.html | 76 + .../-laboratory-extension.html | 76 + .../-laboratory-extension/dependency.html | 76 + .../disabled-feature.html | 76 + .../enabled-feature.html | 76 + .../feature-factory.html | 76 + .../feature-source-factory.html | 76 + .../-laboratory-extension/feature.html | 76 + .../-laboratory-extension/index.html | 243 + .../-laboratory-extension/option-factory.html | 76 + .../-laboratory-extension/package-name.html | 76 + .../sourced-storage.html | 76 + .../-laboratory-plugin.html | 76 + .../-laboratory-plugin/apply.html | 76 + .../-laboratory-plugin/index.html | 119 + .../-option-factory-input/index.html | 115 + .../-option-factory-input/is-public.html | 76 + .../-option-factory-input/package-name.html | 76 + .../-sourced-feature-storage-input/index.html | 115 + .../is-public.html | 76 + .../package-name.html | 76 + .../io.mehow.laboratory.gradle/index.html | 219 + api/laboratory/gradle-plugin/navigation.html | 412 + api/laboratory/inspector/index.html | 95 + .../-deprecation-alignment/-bottom/index.html | 115 + .../-regular/index.html | 115 + .../-selector/index.html | 100 + .../-selector/select.html | 76 + .../-deprecation-alignment/entries.html | 76 + .../-deprecation-alignment/index.html | 217 + .../-deprecation-alignment/value-of.html | 76 + .../-deprecation-alignment/values.html | 76 + .../-deprecation-phenotype/-hide/index.html | 115 + .../-selector/index.html | 100 + .../-selector/select.html | 76 + .../-deprecation-phenotype/-show/index.html | 115 + .../-strikethrough/index.html | 115 + .../-deprecation-phenotype/entries.html | 76 + .../-deprecation-phenotype/index.html | 232 + .../-deprecation-phenotype/value-of.html | 76 + .../-deprecation-phenotype/values.html | 76 + .../-companion/configure.html | 76 + .../-companion/index.html | 115 + .../-companion/start.html | 76 + .../-configuration/-building-step/build.html | 76 + .../deprecation-alignment-selector.html | 76 + .../deprecation-phenotype-selector.html | 76 + .../-configuration/-building-step/index.html | 145 + .../offscreen-section-behavior.html | 76 + .../-configuration/-companion/builder.html | 76 + .../-configuration/-companion/create.html | 76 + .../-configuration/-companion/index.html | 115 + .../feature-factories.html | 76 + .../-feature-factories-step/index.html | 100 + .../-laboratory-step/index.html | 100 + .../-laboratory-step/laboratory.html | 76 + .../-limited/-limited.html | 76 + .../-limited/index.html | 119 + .../-limited/limit.html | 76 + .../-unlimited/index.html | 80 + .../-offscreen-sections-behavior/index.html | 115 + .../-configuration/index.html | 160 + .../-laboratory-activity.html | 76 + .../-laboratory-activity/index.html | 6262 +++++++++++++++ .../io.mehow.laboratory.inspector/index.html | 129 + api/laboratory/inspector/navigation.html | 412 + api/laboratory/runtime/index.html | 95 + .../-blocking-io-call/index.html | 80 + .../-blocking-laboratory/clear.html | 76 + .../-blocking-laboratory/experiment-is.html | 76 + .../-blocking-laboratory/experiment.html | 76 + .../-blocking-laboratory/index.html | 160 + .../-blocking-laboratory/set-option.html | 76 + .../-blocking-laboratory/set-options.html | 76 + .../-companion/index.html | 80 + .../-default-option-factory/create.html | 76 + .../-default-option-factory/index.html | 134 + .../-default-option-factory/plus.html | 76 + .../-feature-factory/-companion/index.html | 80 + .../-feature-factory/create.html | 76 + .../-feature-factory/index.html | 134 + .../-feature-factory/plus.html | 76 + .../-companion/in-memory.html | 76 + .../-feature-storage/-companion/index.html | 115 + .../-feature-storage/-companion/sourced.html | 76 + .../-feature-storage/clear.html | 76 + .../-feature-storage/get-feature-name.html | 76 + .../-feature-storage/index.html | 194 + .../observe-feature-name.html | 76 + .../-feature-storage/set-option.html | 76 + .../-feature-storage/set-options.html | 76 + .../with-default-option-factory.html | 76 + .../-feature/default-option.html | 76 + .../-feature/description.html | 76 + .../io.mehow.laboratory/-feature/index.html | 179 + .../io.mehow.laboratory/-feature/name.html | 76 + .../io.mehow.laboratory/-feature/source.html | 76 + .../-feature/supervisor-option.html | 76 + .../-laboratory/-building-step/build.html | 76 + .../default-option-factory.html | 76 + .../-laboratory/-building-step/index.html | 115 + .../-laboratory/-companion/builder.html | 76 + .../-laboratory/-companion/create.html | 76 + .../-laboratory/-companion/in-memory.html | 76 + .../-laboratory/-companion/index.html | 130 + .../feature-storage.html | 76 + .../-feature-storage-step/index.html | 100 + .../-laboratory/blocking.html | 76 + .../-laboratory/clear.html | 76 + .../-laboratory/experiment-is.html | 76 + .../-laboratory/experiment.html | 76 + .../-laboratory/index.html | 239 + .../-laboratory/observe.html | 76 + .../-laboratory/set-option.html | 76 + .../-laboratory/set-options.html | 76 + .../-option-factory/-companion/index.html | 80 + .../-option-factory/create.html | 76 + .../-option-factory/index.html | 134 + .../-option-factory/plus.html | 76 + .../io.mehow.laboratory/default-option.html | 76 + .../io.mehow.laboratory/description.html | 76 + .../runtime/io.mehow.laboratory/index.html | 283 + .../runtime/io.mehow.laboratory/options.html | 76 + .../runtime/io.mehow.laboratory/source.html | 76 + .../supervisor-option.html | 76 + api/laboratory/runtime/navigation.html | 412 + api/laboratory/shared-preferences/index.html | 95 + .../index.html | 99 + .../shared-preferences.html | 76 + .../shared-preferences/navigation.html | 412 + api/navigation.html | 412 + api/package-list | 15 + api/scripts/clipboard.js | 56 + api/scripts/main.js | 44 + api/scripts/navigation-loader.js | 95 + api/scripts/pages.json | 1 + api/scripts/platform-content-handler.js | 400 + api/scripts/prism.js | 22 + api/scripts/sourceset_dependencies.js | 1 + .../symbol-parameters-wrapper_deferred.js | 64 + api/styles/font-jb-sans-auto.css | 36 + api/styles/logo-styles.css | 9 + api/styles/main.css | 124 + api/styles/prism.css | 217 + api/styles/style.css | 1509 ++++ assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.51d95adb.min.js | 29 + assets/javascripts/bundle.51d95adb.min.js.map | 8 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.e5c33ebb.min.js | 42 + .../workers/search.e5c33ebb.min.js.map | 8 + assets/stylesheets/main.558e4712.min.css | 1 + assets/stylesheets/main.558e4712.min.css.map | 1 + assets/stylesheets/palette.2505c338.min.css | 1 + .../stylesheets/palette.2505c338.min.css.map | 1 + changelog/index.html | 2955 ++++++++ css/site.css | 10 + gradle-plugin/index.html | 1177 +++ images/hyperion_screenshot.jpg | Bin 0 -> 33157 bytes images/inspector_screenshot.jpg | Bin 0 -> 141921 bytes images/laboratory_logo.ico | Bin 0 -> 4286 bytes images/laboratory_logo.svg | 103 + images/laboratory_logo_menu.svg | 6 + index.html | 602 ++ qa-module/index.html | 642 ++ releasing/index.html | 500 ++ requirements.txt | 1 + search/search_index.json | 1 + sitemap.xml | 33 + sitemap.xml.gz | Bin 0 -> 257 bytes user-guide/index.html | 819 ++ 330 files changed, 48573 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 api/images/anchor-copy-button.svg create mode 100644 api/images/arrow_down.svg create mode 100644 api/images/burger.svg create mode 100644 api/images/copy-icon.svg create mode 100644 api/images/copy-successful-icon.svg create mode 100644 api/images/footer-go-to-link.svg create mode 100644 api/images/go-to-top-icon.svg create mode 100644 api/images/homepage.svg create mode 100644 api/images/logo-icon.svg create mode 100644 api/images/nav-icons/abstract-class-kotlin.svg create mode 100644 api/images/nav-icons/abstract-class.svg create mode 100644 api/images/nav-icons/annotation-kotlin.svg create mode 100644 api/images/nav-icons/annotation.svg create mode 100644 api/images/nav-icons/class-kotlin.svg create mode 100644 api/images/nav-icons/class.svg create mode 100644 api/images/nav-icons/enum-kotlin.svg create mode 100644 api/images/nav-icons/enum.svg create mode 100644 api/images/nav-icons/exception-class.svg create mode 100644 api/images/nav-icons/field-value.svg create mode 100644 api/images/nav-icons/field-variable.svg create mode 100644 api/images/nav-icons/function.svg create mode 100644 api/images/nav-icons/interface-kotlin.svg create mode 100644 api/images/nav-icons/interface.svg create mode 100644 api/images/nav-icons/object.svg create mode 100644 api/images/nav-icons/typealias-kotlin.svg create mode 100644 api/images/theme-toggle.svg create mode 100644 api/index.html create mode 100644 api/laboratory/data-store/index.html create mode 100644 api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/default-value.html create mode 100644 api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/index.html create mode 100644 api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/read-from.html create mode 100644 api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/write-to.html create mode 100644 api/laboratory/data-store/io.mehow.laboratory.datastore/data-store.html create mode 100644 api/laboratory/data-store/io.mehow.laboratory.datastore/index.html create mode 100644 api/laboratory/data-store/navigation.html create mode 100644 api/laboratory/generator/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/-deprecation.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/level.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/message.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/-feature-factory-model.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/class-name.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/features.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/prepare.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/visibility.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/-feature-flag-model.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/class-name.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/deprecation.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/description.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/equals.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/hash-code.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/key.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/options.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/prepare.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/source.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/supervisor.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/to-string.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/visibility.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/-feature-flag-option.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/is-default.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/name.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/-option-factory-model.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/class-name.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/features.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/prepare.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/visibility.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/-sourced-feature-storage-model.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/class-name.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/prepare.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/source-names.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/visibility.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/-supervisor.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/feature-flag.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/option.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-internal/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-public/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-visibility/entries.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-visibility/index.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-visibility/value-of.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/-visibility/values.html create mode 100644 api/laboratory/generator/io.mehow.laboratory.generator/index.html create mode 100644 api/laboratory/generator/navigation.html create mode 100644 api/laboratory/gradle-plugin/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/disabled-feature.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/enabled-feature.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/feature.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-factory/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-source-factory/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-option-factory/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-sourced-storage/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/entries.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/value-of.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/values.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-error/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-hidden/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-warning/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/entries.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/value-of.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/values.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/is-public.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/package-name.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/description.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/is-public.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/key.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-disabled.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-enabled.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/description.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/is-public.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/key.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-default-option.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-option.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/deprecated.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/description.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/is-public.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/key.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/package-name.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-default-source.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-source.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/-laboratory-extension.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/dependency.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/disabled-feature.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/enabled-feature.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-factory.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-source-factory.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/option-factory.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/package-name.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/sourced-storage.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/-laboratory-plugin.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/apply.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/is-public.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/package-name.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/index.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/is-public.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/package-name.html create mode 100644 api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/index.html create mode 100644 api/laboratory/gradle-plugin/navigation.html create mode 100644 api/laboratory/inspector/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-bottom/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-regular/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/select.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/entries.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/value-of.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/values.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-hide/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/select.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-show/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-strikethrough/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/entries.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/value-of.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/values.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/configure.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/start.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/build.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-alignment-selector.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-phenotype-selector.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/offscreen-section-behavior.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/builder.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/create.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/feature-factories.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/laboratory.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/-limited.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/limit.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-unlimited/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-laboratory-activity.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/index.html create mode 100644 api/laboratory/inspector/io.mehow.laboratory.inspector/index.html create mode 100644 api/laboratory/inspector/navigation.html create mode 100644 api/laboratory/runtime/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-io-call/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/clear.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment-is.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-option.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-options.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/-companion/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/create.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/plus.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-factory/-companion/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-factory/create.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-factory/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-factory/plus.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/in-memory.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/sourced.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/clear.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/get-feature-name.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/observe-feature-name.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-option.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-options.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature-storage/with-default-option-factory.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature/default-option.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature/description.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature/name.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature/source.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-feature/supervisor-option.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/build.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/default-option-factory.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/builder.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/create.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/in-memory.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/feature-storage.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/blocking.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/clear.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment-is.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/observe.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-option.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-options.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-option-factory/-companion/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-option-factory/create.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-option-factory/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/-option-factory/plus.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/default-option.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/description.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/index.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/options.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/source.html create mode 100644 api/laboratory/runtime/io.mehow.laboratory/supervisor-option.html create mode 100644 api/laboratory/runtime/navigation.html create mode 100644 api/laboratory/shared-preferences/index.html create mode 100644 api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/index.html create mode 100644 api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/shared-preferences.html create mode 100644 api/laboratory/shared-preferences/navigation.html create mode 100644 api/navigation.html create mode 100644 api/package-list create mode 100644 api/scripts/clipboard.js create mode 100644 api/scripts/main.js create mode 100644 api/scripts/navigation-loader.js create mode 100644 api/scripts/pages.json create mode 100644 api/scripts/platform-content-handler.js create mode 100644 api/scripts/prism.js create mode 100644 api/scripts/sourceset_dependencies.js create mode 100644 api/scripts/symbol-parameters-wrapper_deferred.js create mode 100644 api/styles/font-jb-sans-auto.css create mode 100644 api/styles/logo-styles.css create mode 100644 api/styles/main.css create mode 100644 api/styles/prism.css create mode 100644 api/styles/style.css create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.51d95adb.min.js create mode 100644 assets/javascripts/bundle.51d95adb.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.e5c33ebb.min.js create mode 100644 assets/javascripts/workers/search.e5c33ebb.min.js.map create mode 100644 assets/stylesheets/main.558e4712.min.css create mode 100644 assets/stylesheets/main.558e4712.min.css.map create mode 100644 assets/stylesheets/palette.2505c338.min.css create mode 100644 assets/stylesheets/palette.2505c338.min.css.map create mode 100644 changelog/index.html create mode 100644 css/site.css create mode 100644 gradle-plugin/index.html create mode 100644 images/hyperion_screenshot.jpg create mode 100644 images/inspector_screenshot.jpg create mode 100644 images/laboratory_logo.ico create mode 100644 images/laboratory_logo.svg create mode 100644 images/laboratory_logo_menu.svg create mode 100644 index.html create mode 100644 qa-module/index.html create mode 100644 releasing/index.html create mode 100644 requirements.txt create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 user-guide/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..01f367b71 --- /dev/null +++ b/404.html @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + Laboratory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+

Whoops! Looks like the documentation is missing. Please report a bug on GitHub.

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/images/anchor-copy-button.svg b/api/images/anchor-copy-button.svg new file mode 100644 index 000000000..19c1fa3f4 --- /dev/null +++ b/api/images/anchor-copy-button.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/api/images/arrow_down.svg b/api/images/arrow_down.svg new file mode 100644 index 000000000..639aaf12c --- /dev/null +++ b/api/images/arrow_down.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/api/images/burger.svg b/api/images/burger.svg new file mode 100644 index 000000000..fcca732b7 --- /dev/null +++ b/api/images/burger.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/api/images/copy-icon.svg b/api/images/copy-icon.svg new file mode 100644 index 000000000..2cb02ec6e --- /dev/null +++ b/api/images/copy-icon.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/api/images/copy-successful-icon.svg b/api/images/copy-successful-icon.svg new file mode 100644 index 000000000..c4b95383d --- /dev/null +++ b/api/images/copy-successful-icon.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/api/images/footer-go-to-link.svg b/api/images/footer-go-to-link.svg new file mode 100644 index 000000000..a87add7a3 --- /dev/null +++ b/api/images/footer-go-to-link.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/api/images/go-to-top-icon.svg b/api/images/go-to-top-icon.svg new file mode 100644 index 000000000..abc3d1cef --- /dev/null +++ b/api/images/go-to-top-icon.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/api/images/homepage.svg b/api/images/homepage.svg new file mode 100644 index 000000000..e3c83b1ce --- /dev/null +++ b/api/images/homepage.svg @@ -0,0 +1,3 @@ + + + diff --git a/api/images/logo-icon.svg b/api/images/logo-icon.svg new file mode 100644 index 000000000..e42f9570c --- /dev/null +++ b/api/images/logo-icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/api/images/nav-icons/abstract-class-kotlin.svg b/api/images/nav-icons/abstract-class-kotlin.svg new file mode 100644 index 000000000..19d6148ca --- /dev/null +++ b/api/images/nav-icons/abstract-class-kotlin.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/api/images/nav-icons/abstract-class.svg b/api/images/nav-icons/abstract-class.svg new file mode 100644 index 000000000..601820302 --- /dev/null +++ b/api/images/nav-icons/abstract-class.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/api/images/nav-icons/annotation-kotlin.svg b/api/images/nav-icons/annotation-kotlin.svg new file mode 100644 index 000000000..b90f508c4 --- /dev/null +++ b/api/images/nav-icons/annotation-kotlin.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/api/images/nav-icons/annotation.svg b/api/images/nav-icons/annotation.svg new file mode 100644 index 000000000..b80c54b4b --- /dev/null +++ b/api/images/nav-icons/annotation.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/nav-icons/class-kotlin.svg b/api/images/nav-icons/class-kotlin.svg new file mode 100644 index 000000000..797a2423c --- /dev/null +++ b/api/images/nav-icons/class-kotlin.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/api/images/nav-icons/class.svg b/api/images/nav-icons/class.svg new file mode 100644 index 000000000..3f1ad167e --- /dev/null +++ b/api/images/nav-icons/class.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/nav-icons/enum-kotlin.svg b/api/images/nav-icons/enum-kotlin.svg new file mode 100644 index 000000000..775a7cc90 --- /dev/null +++ b/api/images/nav-icons/enum-kotlin.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/api/images/nav-icons/enum.svg b/api/images/nav-icons/enum.svg new file mode 100644 index 000000000..fa7f24766 --- /dev/null +++ b/api/images/nav-icons/enum.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/nav-icons/exception-class.svg b/api/images/nav-icons/exception-class.svg new file mode 100644 index 000000000..c0b2bdeba --- /dev/null +++ b/api/images/nav-icons/exception-class.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/nav-icons/field-value.svg b/api/images/nav-icons/field-value.svg new file mode 100644 index 000000000..2771ee56c --- /dev/null +++ b/api/images/nav-icons/field-value.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/api/images/nav-icons/field-variable.svg b/api/images/nav-icons/field-variable.svg new file mode 100644 index 000000000..e2d2bbd01 --- /dev/null +++ b/api/images/nav-icons/field-variable.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/api/images/nav-icons/function.svg b/api/images/nav-icons/function.svg new file mode 100644 index 000000000..f0da64a0b --- /dev/null +++ b/api/images/nav-icons/function.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/nav-icons/interface-kotlin.svg b/api/images/nav-icons/interface-kotlin.svg new file mode 100644 index 000000000..5e163260e --- /dev/null +++ b/api/images/nav-icons/interface-kotlin.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/api/images/nav-icons/interface.svg b/api/images/nav-icons/interface.svg new file mode 100644 index 000000000..32063ba26 --- /dev/null +++ b/api/images/nav-icons/interface.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/api/images/nav-icons/object.svg b/api/images/nav-icons/object.svg new file mode 100644 index 000000000..31f0ee3e6 --- /dev/null +++ b/api/images/nav-icons/object.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/api/images/nav-icons/typealias-kotlin.svg b/api/images/nav-icons/typealias-kotlin.svg new file mode 100644 index 000000000..f4bb238b5 --- /dev/null +++ b/api/images/nav-icons/typealias-kotlin.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/api/images/theme-toggle.svg b/api/images/theme-toggle.svg new file mode 100644 index 000000000..df86202bb --- /dev/null +++ b/api/images/theme-toggle.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/api/index.html b/api/index.html new file mode 100644 index 000000000..9d2e7cd14 --- /dev/null +++ b/api/index.html @@ -0,0 +1,142 @@ + + + + + All modules + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

All modules:

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
+
+
+
+ +
+
+
+ + diff --git a/api/laboratory/data-store/index.html b/api/laboratory/data-store/index.html new file mode 100644 index 000000000..098d42976 --- /dev/null +++ b/api/laboratory/data-store/index.html @@ -0,0 +1,95 @@ + + + + + data-store + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

data-store

+
+

Packages

+
+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/default-value.html b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/default-value.html new file mode 100644 index 000000000..66e6cab8e --- /dev/null +++ b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/default-value.html @@ -0,0 +1,76 @@ + + + + + defaultValue + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

defaultValue

+
+
open override val defaultValue: <Error class: unknown class>
+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/index.html b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/index.html new file mode 100644 index 000000000..6b2f51df9 --- /dev/null +++ b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/index.html @@ -0,0 +1,134 @@ + + + + + FeatureFlagsSerializer + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFlagsSerializer

+
object FeatureFlagsSerializer : Serializer<<Error class: unknown class>>

Serializer that is capable of writing and reading of feature flags. It can be used, for example, as a delegate of encryption serializer.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override val defaultValue: <Error class: unknown class>
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open suspend override fun readFrom(input: InputStream): <Error class: unknown class>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open suspend override fun writeTo(t: <Error class: unknown class>, output: OutputStream)
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/read-from.html b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/read-from.html new file mode 100644 index 000000000..a97ee523d --- /dev/null +++ b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/read-from.html @@ -0,0 +1,76 @@ + + + + + readFrom + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

readFrom

+
+
open suspend override fun readFrom(input: InputStream): <Error class: unknown class>
+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/write-to.html b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/write-to.html new file mode 100644 index 000000000..723584e8d --- /dev/null +++ b/api/laboratory/data-store/io.mehow.laboratory.datastore/-feature-flags-serializer/write-to.html @@ -0,0 +1,76 @@ + + + + + writeTo + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

writeTo

+
+
open suspend override fun writeTo(t: <Error class: unknown class>, output: OutputStream)
+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/io.mehow.laboratory.datastore/data-store.html b/api/laboratory/data-store/io.mehow.laboratory.datastore/data-store.html new file mode 100644 index 000000000..9e81d0b1b --- /dev/null +++ b/api/laboratory/data-store/io.mehow.laboratory.datastore/data-store.html @@ -0,0 +1,76 @@ + + + + + dataStore + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

dataStore

+
+
fun FeatureStorage.Companion.dataStore(dataStore: DataStore<<Error class: unknown class>>): FeatureStorage

Creates a FeatureStorage that is backed by DataStore.

+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/io.mehow.laboratory.datastore/index.html b/api/laboratory/data-store/io.mehow.laboratory.datastore/index.html new file mode 100644 index 000000000..cba95ce11 --- /dev/null +++ b/api/laboratory/data-store/io.mehow.laboratory.datastore/index.html @@ -0,0 +1,118 @@ + + + + + io.mehow.laboratory.datastore + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Package-level declarations

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
object FeatureFlagsSerializer : Serializer<<Error class: unknown class>>

Serializer that is capable of writing and reading of feature flags. It can be used, for example, as a delegate of encryption serializer.

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun FeatureStorage.Companion.dataStore(dataStore: DataStore<<Error class: unknown class>>): FeatureStorage

Creates a FeatureStorage that is backed by DataStore.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/data-store/navigation.html b/api/laboratory/data-store/navigation.html new file mode 100644 index 000000000..b634800a6 --- /dev/null +++ b/api/laboratory/data-store/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/laboratory/generator/index.html b/api/laboratory/generator/index.html new file mode 100644 index 000000000..d3c6aa765 --- /dev/null +++ b/api/laboratory/generator/index.html @@ -0,0 +1,95 @@ + + + + + generator + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

generator

+
+

Packages

+
+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/-deprecation.html b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/-deprecation.html new file mode 100644 index 000000000..738519957 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/-deprecation.html @@ -0,0 +1,76 @@ + + + + + Deprecation + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Deprecation

+
+
constructor(message: String, level: DeprecationLevel = WARNING)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/index.html new file mode 100644 index 000000000..c1d8e47d1 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/index.html @@ -0,0 +1,134 @@ + + + + + Deprecation + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Deprecation

+
class Deprecation(val message: String, val level: DeprecationLevel = WARNING)
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(message: String, level: DeprecationLevel = WARNING)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/level.html b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/level.html new file mode 100644 index 000000000..0ee6878f2 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/level.html @@ -0,0 +1,76 @@ + + + + + level + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

level

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/message.html b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/message.html new file mode 100644 index 000000000..15f2776c4 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-deprecation/message.html @@ -0,0 +1,76 @@ + + + + + message + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

message

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/-feature-factory-model.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/-feature-factory-model.html new file mode 100644 index 000000000..75d2e78d9 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/-feature-factory-model.html @@ -0,0 +1,76 @@ + + + + + FeatureFactoryModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFactoryModel

+
+
constructor(className: ClassName, features: List<FeatureFlagModel>, visibility: Visibility = Internal)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/class-name.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/class-name.html new file mode 100644 index 000000000..cc039c0a0 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/class-name.html @@ -0,0 +1,76 @@ + + + + + className + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

className

+
+
val className: ClassName
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/features.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/features.html new file mode 100644 index 000000000..6297cf24a --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/features.html @@ -0,0 +1,76 @@ + + + + + features + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

features

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/index.html new file mode 100644 index 000000000..8a096dc71 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/index.html @@ -0,0 +1,168 @@ + + + + + FeatureFactoryModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFactoryModel

+
class FeatureFactoryModel(val className: ClassName, val features: List<FeatureFlagModel>, val visibility: Visibility = Internal)
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(className: ClassName, features: List<FeatureFlagModel>, visibility: Visibility = Internal)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val className: ClassName
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun prepare(functionName: String): FileSpec
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/prepare.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/prepare.html new file mode 100644 index 000000000..ca2e20e1e --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/prepare.html @@ -0,0 +1,76 @@ + + + + + prepare + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

prepare

+
+
fun prepare(functionName: String): FileSpec
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/visibility.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/visibility.html new file mode 100644 index 000000000..7d2d06a8d --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-factory-model/visibility.html @@ -0,0 +1,76 @@ + + + + + visibility + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

visibility

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/-feature-flag-model.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/-feature-flag-model.html new file mode 100644 index 000000000..dfda77271 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/-feature-flag-model.html @@ -0,0 +1,76 @@ + + + + + FeatureFlagModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFlagModel

+
+
constructor(className: ClassName, options: List<FeatureFlagOption>, visibility: Visibility = Public, key: String? = null, description: String = "", deprecation: Deprecation? = null, sourceOptions: List<FeatureFlagOption> = emptyList(), supervisor: Supervisor? = null)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/class-name.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/class-name.html new file mode 100644 index 000000000..09ede864a --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/class-name.html @@ -0,0 +1,76 @@ + + + + + className + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

className

+
+
val className: ClassName
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/deprecation.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/deprecation.html new file mode 100644 index 000000000..54a0c0878 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/deprecation.html @@ -0,0 +1,76 @@ + + + + + deprecation + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

deprecation

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/description.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/description.html new file mode 100644 index 000000000..5b35e8ef0 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/description.html @@ -0,0 +1,76 @@ + + + + + description + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

description

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/equals.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/equals.html new file mode 100644 index 000000000..404d2d6bf --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/equals.html @@ -0,0 +1,76 @@ + + + + + equals + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

equals

+
+
open operator override fun equals(other: Any?): Boolean
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/hash-code.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/hash-code.html new file mode 100644 index 000000000..523514139 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/hash-code.html @@ -0,0 +1,76 @@ + + + + + hashCode + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

hashCode

+
+
open override fun hashCode(): Int
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/index.html new file mode 100644 index 000000000..c971b9ee1 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/index.html @@ -0,0 +1,288 @@ + + + + + FeatureFlagModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFlagModel

+ +
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(className: ClassName, options: List<FeatureFlagOption>, visibility: Visibility = Public, key: String? = null, description: String = "", deprecation: Deprecation? = null, sourceOptions: List<FeatureFlagOption> = emptyList(), supervisor: Supervisor? = null)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val className: ClassName
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
val key: String?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open operator override fun equals(other: Any?): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun hashCode(): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun prepare(): FileSpec
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun toString(): String
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/key.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/key.html new file mode 100644 index 000000000..2fe808fae --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/key.html @@ -0,0 +1,76 @@ + + + + + key + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

key

+
+
val key: String?
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/options.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/options.html new file mode 100644 index 000000000..edf965e13 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/options.html @@ -0,0 +1,76 @@ + + + + + options + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

options

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/prepare.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/prepare.html new file mode 100644 index 000000000..e3d864445 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/prepare.html @@ -0,0 +1,76 @@ + + + + + prepare + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

prepare

+
+
fun prepare(): FileSpec
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/source.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/source.html new file mode 100644 index 000000000..56489841f --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/source.html @@ -0,0 +1,76 @@ + + + + + source + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

source

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/supervisor.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/supervisor.html new file mode 100644 index 000000000..4e0f2603d --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/supervisor.html @@ -0,0 +1,76 @@ + + + + + supervisor + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

supervisor

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/to-string.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/to-string.html new file mode 100644 index 000000000..6095fcf67 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/to-string.html @@ -0,0 +1,76 @@ + + + + + toString + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

toString

+
+
open override fun toString(): String
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/visibility.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/visibility.html new file mode 100644 index 000000000..a8229a8e2 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-model/visibility.html @@ -0,0 +1,76 @@ + + + + + visibility + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

visibility

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/-feature-flag-option.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/-feature-flag-option.html new file mode 100644 index 000000000..cfec2315b --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/-feature-flag-option.html @@ -0,0 +1,76 @@ + + + + + FeatureFlagOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFlagOption

+
+
constructor(name: String, isDefault: Boolean = false)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/index.html new file mode 100644 index 000000000..3fd4db8b9 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/index.html @@ -0,0 +1,134 @@ + + + + + FeatureFlagOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFlagOption

+
data class FeatureFlagOption(val name: String, val isDefault: Boolean = false)
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(name: String, isDefault: Boolean = false)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val isDefault: Boolean = false
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/is-default.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/is-default.html new file mode 100644 index 000000000..c48cc6d6b --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/is-default.html @@ -0,0 +1,76 @@ + + + + + isDefault + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isDefault

+
+
val isDefault: Boolean = false
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/name.html b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/name.html new file mode 100644 index 000000000..6a4aa5240 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-feature-flag-option/name.html @@ -0,0 +1,76 @@ + + + + + name + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

name

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/-option-factory-model.html b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/-option-factory-model.html new file mode 100644 index 000000000..65d7b6109 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/-option-factory-model.html @@ -0,0 +1,76 @@ + + + + + OptionFactoryModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

OptionFactoryModel

+
+
constructor(className: ClassName, features: List<FeatureFlagModel>, visibility: Visibility = Internal)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/class-name.html b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/class-name.html new file mode 100644 index 000000000..ec1b20ae8 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/class-name.html @@ -0,0 +1,76 @@ + + + + + className + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

className

+
+
val className: ClassName
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/features.html b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/features.html new file mode 100644 index 000000000..0f96796fa --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/features.html @@ -0,0 +1,76 @@ + + + + + features + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

features

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/index.html new file mode 100644 index 000000000..fed4376b1 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/index.html @@ -0,0 +1,168 @@ + + + + + OptionFactoryModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

OptionFactoryModel

+
class OptionFactoryModel(val className: ClassName, val features: List<FeatureFlagModel>, val visibility: Visibility = Internal)
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(className: ClassName, features: List<FeatureFlagModel>, visibility: Visibility = Internal)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val className: ClassName
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun prepare(): FileSpec
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/prepare.html b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/prepare.html new file mode 100644 index 000000000..61e1eba51 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/prepare.html @@ -0,0 +1,76 @@ + + + + + prepare + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

prepare

+
+
fun prepare(): FileSpec
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/visibility.html b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/visibility.html new file mode 100644 index 000000000..1dcd44f0e --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-option-factory-model/visibility.html @@ -0,0 +1,76 @@ + + + + + visibility + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

visibility

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/-sourced-feature-storage-model.html b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/-sourced-feature-storage-model.html new file mode 100644 index 000000000..03cb6481b --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/-sourced-feature-storage-model.html @@ -0,0 +1,76 @@ + + + + + SourcedFeatureStorageModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

SourcedFeatureStorageModel

+
+
constructor(className: ClassName, sourceNames: List<String>, visibility: Visibility = Internal)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/class-name.html b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/class-name.html new file mode 100644 index 000000000..a99e4dabb --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/class-name.html @@ -0,0 +1,76 @@ + + + + + className + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

className

+
+
val className: ClassName
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/index.html new file mode 100644 index 000000000..cc946af3c --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/index.html @@ -0,0 +1,168 @@ + + + + + SourcedFeatureStorageModel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

SourcedFeatureStorageModel

+
class SourcedFeatureStorageModel(val className: ClassName, val sourceNames: List<String>, val visibility: Visibility = Internal)
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(className: ClassName, sourceNames: List<String>, visibility: Visibility = Internal)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val className: ClassName
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun prepare(): FileSpec
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/prepare.html b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/prepare.html new file mode 100644 index 000000000..2848a77e7 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/prepare.html @@ -0,0 +1,76 @@ + + + + + prepare + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

prepare

+
+
fun prepare(): FileSpec
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/source-names.html b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/source-names.html new file mode 100644 index 000000000..c7949627e --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/source-names.html @@ -0,0 +1,76 @@ + + + + + sourceNames + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

sourceNames

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/visibility.html b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/visibility.html new file mode 100644 index 000000000..24ddb4daa --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-sourced-feature-storage-model/visibility.html @@ -0,0 +1,76 @@ + + + + + visibility + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

visibility

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/-supervisor.html b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/-supervisor.html new file mode 100644 index 000000000..83b071e83 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/-supervisor.html @@ -0,0 +1,76 @@ + + + + + Supervisor + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Supervisor

+
+
constructor(featureFlag: FeatureFlagModel, option: FeatureFlagOption)
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/feature-flag.html b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/feature-flag.html new file mode 100644 index 000000000..d807b9b9c --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/feature-flag.html @@ -0,0 +1,76 @@ + + + + + featureFlag + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

featureFlag

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/index.html new file mode 100644 index 000000000..23e90d606 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/index.html @@ -0,0 +1,134 @@ + + + + + Supervisor + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Supervisor

+
class Supervisor(val featureFlag: FeatureFlagModel, val option: FeatureFlagOption)
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(featureFlag: FeatureFlagModel, option: FeatureFlagOption)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/option.html b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/option.html new file mode 100644 index 000000000..99f74aa55 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-supervisor/option.html @@ -0,0 +1,76 @@ + + + + + option + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

option

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-internal/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-internal/index.html new file mode 100644 index 000000000..425c8277a --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-internal/index.html @@ -0,0 +1,115 @@ + + + + + Internal + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Internal

+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-public/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-public/index.html new file mode 100644 index 000000000..4cd188ef7 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/-public/index.html @@ -0,0 +1,115 @@ + + + + + Public + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Public

+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/entries.html b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/entries.html new file mode 100644 index 000000000..27a8fc80c --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/entries.html @@ -0,0 +1,76 @@ + + + + + entries + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

entries

+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

This method may be used to iterate over the enum entries.

+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/index.html new file mode 100644 index 000000000..603fbd7bc --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/index.html @@ -0,0 +1,198 @@ + + + + + Visibility + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Visibility

+ +
+
+
+
+
+

Entries

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns an array containing the constants of this enum type, in the order they're declared.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/value-of.html b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/value-of.html new file mode 100644 index 000000000..b6cad0267 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/value-of.html @@ -0,0 +1,76 @@ + + + + + valueOf + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

valueOf

+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Throws

if this enum type has no constant with the specified name

+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/values.html b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/values.html new file mode 100644 index 000000000..4ea6c0ad6 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/-visibility/values.html @@ -0,0 +1,76 @@ + + + + + values + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

values

+
+

Returns an array containing the constants of this enum type, in the order they're declared.

This method may be used to iterate over the constants.

+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/io.mehow.laboratory.generator/index.html b/api/laboratory/generator/io.mehow.laboratory.generator/index.html new file mode 100644 index 000000000..3c6528b99 --- /dev/null +++ b/api/laboratory/generator/io.mehow.laboratory.generator/index.html @@ -0,0 +1,204 @@ + + + + + io.mehow.laboratory.generator + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Package-level declarations

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
class Deprecation(val message: String, val level: DeprecationLevel = WARNING)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
class FeatureFactoryModel(val className: ClassName, val features: List<FeatureFlagModel>, val visibility: Visibility = Internal)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
data class FeatureFlagOption(val name: String, val isDefault: Boolean = false)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
class OptionFactoryModel(val className: ClassName, val features: List<FeatureFlagModel>, val visibility: Visibility = Internal)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
class SourcedFeatureStorageModel(val className: ClassName, val sourceNames: List<String>, val visibility: Visibility = Internal)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
class Supervisor(val featureFlag: FeatureFlagModel, val option: FeatureFlagOption)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/generator/navigation.html b/api/laboratory/generator/navigation.html new file mode 100644 index 000000000..b634800a6 --- /dev/null +++ b/api/laboratory/generator/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/laboratory/gradle-plugin/index.html b/api/laboratory/gradle-plugin/index.html new file mode 100644 index 000000000..9131aa2fa --- /dev/null +++ b/api/laboratory/gradle-plugin/index.html @@ -0,0 +1,95 @@ + + + + + gradle-plugin + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

gradle-plugin

+
+

Packages

+
+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/disabled-feature.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/disabled-feature.html new file mode 100644 index 000000000..c1a21f847 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/disabled-feature.html @@ -0,0 +1,76 @@ + + + + + disabledFeature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

disabledFeature

+
+
fun disabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is disabled by default.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/enabled-feature.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/enabled-feature.html new file mode 100644 index 000000000..9f9cd7212 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/enabled-feature.html @@ -0,0 +1,76 @@ + + + + + enabledFeature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

enabledFeature

+
+
fun enabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is enabled by default.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/feature.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/feature.html new file mode 100644 index 000000000..546439a87 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/feature.html @@ -0,0 +1,76 @@ + + + + + feature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

feature

+
+
fun feature(name: String, action: Action<FeatureFlagInput.MultiOption>)

Generates a new supervised multi-option feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/index.html new file mode 100644 index 000000000..ab7a11089 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-child-feature-flags-input/index.html @@ -0,0 +1,130 @@ + + + + + ChildFeatureFlagsInput + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

ChildFeatureFlagsInput

+

An entry point for configuration of supervised feature flags code generation.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun disabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is disabled by default.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun enabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is enabled by default.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun feature(name: String, action: Action<FeatureFlagInput.MultiOption>)

Generates a new supervised multi-option feature flag.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-factory/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-factory/index.html new file mode 100644 index 000000000..22715606e --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-factory/index.html @@ -0,0 +1,115 @@ + + + + + FeatureFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFactory

+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-source-factory/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-source-factory/index.html new file mode 100644 index 000000000..7b686b3ad --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-feature-source-factory/index.html @@ -0,0 +1,115 @@ + + + + + FeatureSourceFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureSourceFactory

+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-option-factory/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-option-factory/index.html new file mode 100644 index 000000000..8c43644e9 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-option-factory/index.html @@ -0,0 +1,115 @@ + + + + + OptionFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

OptionFactory

+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-sourced-storage/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-sourced-storage/index.html new file mode 100644 index 000000000..212c5585e --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/-sourced-storage/index.html @@ -0,0 +1,115 @@ + + + + + SourcedStorage + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

SourcedStorage

+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/entries.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/entries.html new file mode 100644 index 000000000..806347c34 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/entries.html @@ -0,0 +1,76 @@ + + + + + entries + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

entries

+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

This method may be used to iterate over the enum entries.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/index.html new file mode 100644 index 000000000..2022c3ca6 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/index.html @@ -0,0 +1,228 @@ + + + + + DependencyContribution + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

DependencyContribution

+

Possible contributions of a dependency to feature flag generation. See LaboratoryExtension.dependency for more info.

+
+
+
+
+
+

Entries

+
+
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns an array containing the constants of this enum type, in the order they're declared.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/value-of.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/value-of.html new file mode 100644 index 000000000..8dc965938 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/value-of.html @@ -0,0 +1,76 @@ + + + + + valueOf + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

valueOf

+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Throws

if this enum type has no constant with the specified name

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/values.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/values.html new file mode 100644 index 000000000..7fd69313d --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-dependency-contribution/values.html @@ -0,0 +1,76 @@ + + + + + values + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

values

+
+

Returns an array containing the constants of this enum type, in the order they're declared.

This method may be used to iterate over the constants.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-error/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-error/index.html new file mode 100644 index 000000000..043bcf994 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-error/index.html @@ -0,0 +1,115 @@ + + + + + Error + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Error

+

Usage of the deprecated element will be reported as an error.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-hidden/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-hidden/index.html new file mode 100644 index 000000000..f20d44b58 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-hidden/index.html @@ -0,0 +1,115 @@ + + + + + Hidden + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Hidden

+

Deprecated element will not be accessible from code.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-warning/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-warning/index.html new file mode 100644 index 000000000..413d499b1 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/-warning/index.html @@ -0,0 +1,115 @@ + + + + + Warning + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Warning

+

Usage of the deprecated element will be reported as a warning.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/entries.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/entries.html new file mode 100644 index 000000000..d7f1dc595 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/entries.html @@ -0,0 +1,76 @@ + + + + + entries + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

entries

+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

This method may be used to iterate over the enum entries.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/index.html new file mode 100644 index 000000000..b67f2586d --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/index.html @@ -0,0 +1,213 @@ + + + + + DeprecationLevel + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

DeprecationLevel

+

Possible levels of a deprecation. The level specifies how the deprecated element usages are reported in code.

+
+
+
+
+
+

Entries

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Usage of the deprecated element will be reported as a warning.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Usage of the deprecated element will be reported as an error.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Deprecated element will not be accessible from code.

+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns an array containing the constants of this enum type, in the order they're declared.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/value-of.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/value-of.html new file mode 100644 index 000000000..2f7a0c109 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/value-of.html @@ -0,0 +1,76 @@ + + + + + valueOf + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

valueOf

+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Throws

if this enum type has no constant with the specified name

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/values.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/values.html new file mode 100644 index 000000000..8e772cf78 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-deprecation-level/values.html @@ -0,0 +1,76 @@ + + + + + values + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

values

+
+

Returns an array containing the constants of this enum type, in the order they're declared.

This method may be used to iterate over the constants.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/index.html new file mode 100644 index 000000000..eccf3cd68 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/index.html @@ -0,0 +1,115 @@ + + + + + FeatureFactoryInput + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFactoryInput

+

Representation of a generated feature factory class.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets whether the generated feature factory should be public or internal.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name of the generated feature factory. Overwrites any previously set values.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/is-public.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/is-public.html new file mode 100644 index 000000000..8cd8d8245 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/is-public.html @@ -0,0 +1,76 @@ + + + + + isPublic + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isPublic

+
+

Sets whether the generated feature factory should be public or internal.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/package-name.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/package-name.html new file mode 100644 index 000000000..fa0a601b5 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-factory-input/package-name.html @@ -0,0 +1,76 @@ + + + + + packageName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

packageName

+
+

Sets package name of the generated feature factory. Overwrites any previously set values.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/description.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/description.html new file mode 100644 index 000000000..16f4c4730 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/description.html @@ -0,0 +1,76 @@ + + + + + description + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

description

+
+
open override var description: String?

Sets description of the generated feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/index.html new file mode 100644 index 000000000..3adaf4373 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/index.html @@ -0,0 +1,224 @@ + + + + + BinaryOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

BinaryOption

+

Representation of a feature flag with only two options - "Enabled" and "Disabled".

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override var description: String?

Sets description of the generated feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override var isPublic: Boolean

Sets whether the generated feature flag should be public or internal.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override var key: String?

Sets a custom key that will be used for generated option factory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name of the generated feature flag. Overwrites any previously set values.

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun deprecated(message: String, level: DeprecationLevel = DeprecationLevel.Warning)

Annotates a feature flag as deprecated.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Adds a feature flag source that will be used a default source. Any sources that are named "Local", or any variation of this word, will be filtered out. At most one value can be set with this method.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Configures "Disabled" option.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun withEnabled(action: Action<ChildFeatureFlagsInput>)

Configures "Enabled" option.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun withSource(name: String)

Adds a feature flag source. Any sources that are named "Local", or any variation of this word, will be filtered out.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/is-public.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/is-public.html new file mode 100644 index 000000000..59ced1a0c --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/is-public.html @@ -0,0 +1,76 @@ + + + + + isPublic + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isPublic

+
+
open override var isPublic: Boolean

Sets whether the generated feature flag should be public or internal.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/key.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/key.html new file mode 100644 index 000000000..3eed87622 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/key.html @@ -0,0 +1,76 @@ + + + + + key + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

key

+
+
open override var key: String?

Sets a custom key that will be used for generated option factory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-disabled.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-disabled.html new file mode 100644 index 000000000..515f81256 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-disabled.html @@ -0,0 +1,76 @@ + + + + + withDisabled + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withDisabled

+
+

Configures "Disabled" option.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-enabled.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-enabled.html new file mode 100644 index 000000000..407501e80 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-binary-option/with-enabled.html @@ -0,0 +1,76 @@ + + + + + withEnabled + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withEnabled

+
+
fun withEnabled(action: Action<ChildFeatureFlagsInput>)

Configures "Enabled" option.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/description.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/description.html new file mode 100644 index 000000000..b3919a26a --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/description.html @@ -0,0 +1,76 @@ + + + + + description + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

description

+
+
open override var description: String?

Sets description of the generated feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/index.html new file mode 100644 index 000000000..64841c9a8 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/index.html @@ -0,0 +1,224 @@ + + + + + MultiOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

MultiOption

+

Representation of a feature flag with multiple options. It must have at least one option and exactly one default option.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override var description: String?

Sets description of the generated feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override var isPublic: Boolean

Sets whether the generated feature flag should be public or internal.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override var key: String?

Sets a custom key that will be used for generated option factory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name of the generated feature flag. Overwrites any previously set values.

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun deprecated(message: String, level: DeprecationLevel = DeprecationLevel.Warning)

Annotates a feature flag as deprecated.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Adds a feature value that will be used as a default value. Exactly one value must be set with this method.

fun withDefaultOption(name: String, action: Action<ChildFeatureFlagsInput>)

Adds a feature value that will be used as a default value and configures features flags supervised by it. Exactly one value must be set with this method.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Adds a feature flag source that will be used a default source. Any sources that are named "Local", or any variation of this word, will be filtered out. At most one value can be set with this method.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun withOption(name: String)

Adds a feature option.

fun withOption(name: String, action: Action<ChildFeatureFlagsInput>)

Adds a feature option and configures features flags supervised by it.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun withSource(name: String)

Adds a feature flag source. Any sources that are named "Local", or any variation of this word, will be filtered out.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/is-public.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/is-public.html new file mode 100644 index 000000000..0dc37037e --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/is-public.html @@ -0,0 +1,76 @@ + + + + + isPublic + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isPublic

+
+
open override var isPublic: Boolean

Sets whether the generated feature flag should be public or internal.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/key.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/key.html new file mode 100644 index 000000000..a27f42d6a --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/key.html @@ -0,0 +1,76 @@ + + + + + key + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

key

+
+
open override var key: String?

Sets a custom key that will be used for generated option factory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-default-option.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-default-option.html new file mode 100644 index 000000000..06a99a82e --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-default-option.html @@ -0,0 +1,76 @@ + + + + + withDefaultOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withDefaultOption

+
+

Adds a feature value that will be used as a default value. Exactly one value must be set with this method.


fun withDefaultOption(name: String, action: Action<ChildFeatureFlagsInput>)

Adds a feature value that will be used as a default value and configures features flags supervised by it. Exactly one value must be set with this method.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-option.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-option.html new file mode 100644 index 000000000..3bd80164a --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/-multi-option/with-option.html @@ -0,0 +1,76 @@ + + + + + withOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withOption

+
+
fun withOption(name: String)

Adds a feature option.


fun withOption(name: String, action: Action<ChildFeatureFlagsInput>)

Adds a feature option and configures features flags supervised by it.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/deprecated.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/deprecated.html new file mode 100644 index 000000000..aa8182010 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/deprecated.html @@ -0,0 +1,76 @@ + + + + + deprecated + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

deprecated

+
+
fun deprecated(message: String, level: DeprecationLevel = DeprecationLevel.Warning)

Annotates a feature flag as deprecated.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/description.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/description.html new file mode 100644 index 000000000..df2542f29 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/description.html @@ -0,0 +1,76 @@ + + + + + description + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

description

+
+
abstract var description: String?

Sets description of the generated feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/index.html new file mode 100644 index 000000000..d84778e72 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/index.html @@ -0,0 +1,228 @@ + + + + + FeatureFlagInput + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFlagInput

+

Representation of a feature flag with multiple options. Can be either MultiOption or BinaryOption.

Inheritors

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Representation of a feature flag with only two options - "Enabled" and "Disabled".

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Representation of a feature flag with multiple options. It must have at least one option and exactly one default option.

+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract var description: String?

Sets description of the generated feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract var isPublic: Boolean

Sets whether the generated feature flag should be public or internal.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract var key: String?

Sets a custom key that will be used for generated option factory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name of the generated feature flag. Overwrites any previously set values.

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun deprecated(message: String, level: DeprecationLevel = DeprecationLevel.Warning)

Annotates a feature flag as deprecated.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Adds a feature flag source that will be used a default source. Any sources that are named "Local", or any variation of this word, will be filtered out. At most one value can be set with this method.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun withSource(name: String)

Adds a feature flag source. Any sources that are named "Local", or any variation of this word, will be filtered out.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/is-public.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/is-public.html new file mode 100644 index 000000000..6e7c4a9ff --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/is-public.html @@ -0,0 +1,76 @@ + + + + + isPublic + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isPublic

+
+
abstract var isPublic: Boolean

Sets whether the generated feature flag should be public or internal.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/key.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/key.html new file mode 100644 index 000000000..84e87c3df --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/key.html @@ -0,0 +1,76 @@ + + + + + key + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

key

+
+
abstract var key: String?

Sets a custom key that will be used for generated option factory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/package-name.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/package-name.html new file mode 100644 index 000000000..a51004c36 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/package-name.html @@ -0,0 +1,76 @@ + + + + + packageName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

packageName

+
+

Sets package name of the generated feature flag. Overwrites any previously set values.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-default-source.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-default-source.html new file mode 100644 index 000000000..37cda6726 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-default-source.html @@ -0,0 +1,76 @@ + + + + + withDefaultSource + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withDefaultSource

+
+

Adds a feature flag source that will be used a default source. Any sources that are named "Local", or any variation of this word, will be filtered out. At most one value can be set with this method.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-source.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-source.html new file mode 100644 index 000000000..77a07960b --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-feature-flag-input/with-source.html @@ -0,0 +1,76 @@ + + + + + withSource + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withSource

+
+
fun withSource(name: String)

Adds a feature flag source. Any sources that are named "Local", or any variation of this word, will be filtered out.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/-laboratory-extension.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/-laboratory-extension.html new file mode 100644 index 000000000..e8a7c0e2f --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/-laboratory-extension.html @@ -0,0 +1,76 @@ + + + + + LaboratoryExtension + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryExtension

+
+
constructor()
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/dependency.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/dependency.html new file mode 100644 index 000000000..574a609cc --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/dependency.html @@ -0,0 +1,76 @@ + + + + + dependency + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

dependency

+
+
fun dependency(project: DelegatingProjectDependency, contributeTo: Collection<DependencyContribution> = DependencyContribution.entries)
fun dependency(project: Project, contributeTo: Collection<DependencyContribution> = DependencyContribution.entries)

Includes a project during feature flags contribution to featureFactory, featureSourcesFactory, sourcedStorage or optionFactory. Contribution can be selective applied by supplying contributeTo collection.

Included project must have Laboratory plugin applied.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/disabled-feature.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/disabled-feature.html new file mode 100644 index 000000000..997006b50 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/disabled-feature.html @@ -0,0 +1,76 @@ + + + + + disabledFeature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

disabledFeature

+
+
fun disabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is disabled by default.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/enabled-feature.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/enabled-feature.html new file mode 100644 index 000000000..1c7887841 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/enabled-feature.html @@ -0,0 +1,76 @@ + + + + + enabledFeature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

enabledFeature

+
+
fun enabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is enabled by default.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-factory.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-factory.html new file mode 100644 index 000000000..46cb7aad2 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-factory.html @@ -0,0 +1,76 @@ + + + + + featureFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

featureFactory

+
+

Generates a new feature factory in this module. This should generally be used only by a top level module that needs to have information about all feature flags for QA purposes.


fun featureFactory(action: Action<FeatureFactoryInput>)

Generates and customizes a new feature factory in this module. This should generally be used only by a top level module that needs to have information about all feature flags for QA purposes.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-source-factory.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-source-factory.html new file mode 100644 index 000000000..e5a6f659d --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature-source-factory.html @@ -0,0 +1,76 @@ + + + + + featureSourceFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

featureSourceFactory

+
+

Generates a new feature sources factory in this module. This should generally be used only by a top level module that needs to have information about all feature flags for QA purposes.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature.html new file mode 100644 index 000000000..b53998796 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/feature.html @@ -0,0 +1,76 @@ + + + + + feature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

feature

+
+
fun feature(name: String, action: Action<FeatureFlagInput.MultiOption>)

Generates a new multi-option feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/index.html new file mode 100644 index 000000000..358b1a528 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/index.html @@ -0,0 +1,243 @@ + + + + + LaboratoryExtension + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryExtension

+
abstract class LaboratoryExtension

An entry point for configuration of feature flags code generation.

+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor()
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name for any factories or feature flags defined in this extension. Package names can be individually overwritten in each generating block

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun dependency(project: Project, contributeTo: Collection<DependencyContribution> = DependencyContribution.entries)
fun dependency(project: DelegatingProjectDependency, contributeTo: Collection<DependencyContribution> = DependencyContribution.entries)

Includes a project during feature flags contribution to featureFactory, featureSourcesFactory, sourcedStorage or optionFactory. Contribution can be selective applied by supplying contributeTo collection.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun disabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is disabled by default.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun enabledFeature(name: String, action: Action<FeatureFlagInput.BinaryOption> = Action { })

Generates a new supervised binary feature flag that is enabled by default.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun feature(name: String, action: Action<FeatureFlagInput.MultiOption>)

Generates a new multi-option feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Generates a new feature factory in this module. This should generally be used only by a top level module that needs to have information about all feature flags for QA purposes.

fun featureFactory(action: Action<FeatureFactoryInput>)

Generates and customizes a new feature factory in this module. This should generally be used only by a top level module that needs to have information about all feature flags for QA purposes.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Generates a new feature sources factory in this module. This should generally be used only by a top level module that needs to have information about all feature flags for QA purposes.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun optionFactory(action: Action<OptionFactoryInput>)

Generates a new option factory in this module. All features that can be created by this factory must be visible to it during compilation.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Generates a new feature storage in this module. This should generally be used only by a top level module that needs to to have information about all sources. Feature storage generated by this method should be then used in the application.

Generates and customizes a new feature storage in this module. This should generally be used only by a top level module that needs to to have information about all sources. Feature storage generated by this method should be then used in the application.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/option-factory.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/option-factory.html new file mode 100644 index 000000000..312982b99 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/option-factory.html @@ -0,0 +1,76 @@ + + + + + optionFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

optionFactory

+
+
fun optionFactory(action: Action<OptionFactoryInput>)

Generates a new option factory in this module. All features that can be created by this factory must be visible to it during compilation.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/package-name.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/package-name.html new file mode 100644 index 000000000..e00fb09b9 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/package-name.html @@ -0,0 +1,76 @@ + + + + + packageName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

packageName

+
+

Sets package name for any factories or feature flags defined in this extension. Package names can be individually overwritten in each generating block

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/sourced-storage.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/sourced-storage.html new file mode 100644 index 000000000..5b7d441c1 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-extension/sourced-storage.html @@ -0,0 +1,76 @@ + + + + + sourcedStorage + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

sourcedStorage

+
+

Generates a new feature storage in this module. This should generally be used only by a top level module that needs to to have information about all sources. Feature storage generated by this method should be then used in the application.


Generates and customizes a new feature storage in this module. This should generally be used only by a top level module that needs to to have information about all sources. Feature storage generated by this method should be then used in the application.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/-laboratory-plugin.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/-laboratory-plugin.html new file mode 100644 index 000000000..d40898fe0 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/-laboratory-plugin.html @@ -0,0 +1,76 @@ + + + + + LaboratoryPlugin + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryPlugin

+
+
constructor()
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/apply.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/apply.html new file mode 100644 index 000000000..788b71ac1 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/apply.html @@ -0,0 +1,76 @@ + + + + + apply + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

apply

+
+
open override fun apply(target: Project)
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/index.html new file mode 100644 index 000000000..24e54e8b1 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-laboratory-plugin/index.html @@ -0,0 +1,119 @@ + + + + + LaboratoryPlugin + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryPlugin

+
class LaboratoryPlugin : Plugin<Project>
+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor()
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun apply(target: Project)
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/index.html new file mode 100644 index 000000000..a8a8dfe9e --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/index.html @@ -0,0 +1,115 @@ + + + + + OptionFactoryInput + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

OptionFactoryInput

+

Representation of a generated option factory that is aware of feature flags.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets whether the generated option factory should be public or internal.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name of the generated option factory. Overwrites any previously set values.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/is-public.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/is-public.html new file mode 100644 index 000000000..284315353 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/is-public.html @@ -0,0 +1,76 @@ + + + + + isPublic + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isPublic

+
+

Sets whether the generated option factory should be public or internal.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/package-name.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/package-name.html new file mode 100644 index 000000000..85c52fa70 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-option-factory-input/package-name.html @@ -0,0 +1,76 @@ + + + + + packageName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

packageName

+
+

Sets package name of the generated option factory. Overwrites any previously set values.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/index.html new file mode 100644 index 000000000..2cde5b1b6 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/index.html @@ -0,0 +1,115 @@ + + + + + SourcedFeatureStorageInput + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

SourcedFeatureStorageInput

+

Representation of a generated feature storage that is aware of feature flags sources.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets whether the generated feature storage should be public or internal.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets package name of the generated feature storage. Overwrites any previously set values.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/is-public.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/is-public.html new file mode 100644 index 000000000..b9469d4c1 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/is-public.html @@ -0,0 +1,76 @@ + + + + + isPublic + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

isPublic

+
+

Sets whether the generated feature storage should be public or internal.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/package-name.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/package-name.html new file mode 100644 index 000000000..541d6935a --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/-sourced-feature-storage-input/package-name.html @@ -0,0 +1,76 @@ + + + + + packageName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

packageName

+
+

Sets package name of the generated feature storage. Overwrites any previously set values.

+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/index.html b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/index.html new file mode 100644 index 000000000..6e30631e1 --- /dev/null +++ b/api/laboratory/gradle-plugin/io.mehow.laboratory.gradle/index.html @@ -0,0 +1,219 @@ + + + + + io.mehow.laboratory.gradle + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Package-level declarations

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

An entry point for configuration of supervised feature flags code generation.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Possible contributions of a dependency to feature flag generation. See LaboratoryExtension.dependency for more info.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Possible levels of a deprecation. The level specifies how the deprecated element usages are reported in code.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Representation of a generated feature factory class.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Representation of a feature flag with multiple options. Can be either MultiOption or BinaryOption.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract class LaboratoryExtension

An entry point for configuration of feature flags code generation.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
class LaboratoryPlugin : Plugin<Project>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Representation of a generated option factory that is aware of feature flags.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Representation of a generated feature storage that is aware of feature flags sources.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/gradle-plugin/navigation.html b/api/laboratory/gradle-plugin/navigation.html new file mode 100644 index 000000000..b634800a6 --- /dev/null +++ b/api/laboratory/gradle-plugin/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/laboratory/inspector/index.html b/api/laboratory/inspector/index.html new file mode 100644 index 000000000..f02b01dba --- /dev/null +++ b/api/laboratory/inspector/index.html @@ -0,0 +1,95 @@ + + + + + inspector + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

inspector

+
+

Packages

+
+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-bottom/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-bottom/index.html new file mode 100644 index 000000000..3fb978302 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-bottom/index.html @@ -0,0 +1,115 @@ + + + + + Bottom + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Bottom

+

Places deprecated feature flags at the bottom of a list.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-regular/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-regular/index.html new file mode 100644 index 000000000..e98f28f49 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-regular/index.html @@ -0,0 +1,115 @@ + + + + + Regular + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Regular

+

Does not place feature flags in any particular place of a list.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/index.html new file mode 100644 index 000000000..71a99e700 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/index.html @@ -0,0 +1,100 @@ + + + + + Selector + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Selector

+
fun interface Selector

Determines alignment of features flags in a list based on their DeprecationLevel.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Selects DeprecationAlignment based on a feature flag deprecation level.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/select.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/select.html new file mode 100644 index 000000000..ec5543abf --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/-selector/select.html @@ -0,0 +1,76 @@ + + + + + select + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

select

+
+

Selects DeprecationAlignment based on a feature flag deprecation level.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/entries.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/entries.html new file mode 100644 index 000000000..0c6295bf0 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/entries.html @@ -0,0 +1,76 @@ + + + + + entries + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

entries

+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

This method may be used to iterate over the enum entries.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/index.html new file mode 100644 index 000000000..2067dea46 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/index.html @@ -0,0 +1,217 @@ + + + + + DeprecationAlignment + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

DeprecationAlignment

+

Alignment of deprecated feature flags in a list.

+
+
+
+
+
+

Entries

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Does not place feature flags in any particular place of a list.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Places deprecated feature flags at the bottom of a list.

+
+
+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun interface Selector

Determines alignment of features flags in a list based on their DeprecationLevel.

+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns an array containing the constants of this enum type, in the order they're declared.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/value-of.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/value-of.html new file mode 100644 index 000000000..fbd1eae96 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/value-of.html @@ -0,0 +1,76 @@ + + + + + valueOf + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

valueOf

+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Throws

if this enum type has no constant with the specified name

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/values.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/values.html new file mode 100644 index 000000000..7d9a2bf2d --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-alignment/values.html @@ -0,0 +1,76 @@ + + + + + values + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

values

+
+

Returns an array containing the constants of this enum type, in the order they're declared.

This method may be used to iterate over the constants.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-hide/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-hide/index.html new file mode 100644 index 000000000..136a185a9 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-hide/index.html @@ -0,0 +1,115 @@ + + + + + Hide + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Hide

+

Removed feature flag from a list.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/index.html new file mode 100644 index 000000000..1a4e5e811 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/index.html @@ -0,0 +1,100 @@ + + + + + Selector + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Selector

+
fun interface Selector

Determines UI representation of feature flags based on their DeprecationLevel.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Selects DeprecationPhenotype based on a feature flag deprecation level.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/select.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/select.html new file mode 100644 index 000000000..8b6cf16f6 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-selector/select.html @@ -0,0 +1,76 @@ + + + + + select + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

select

+
+

Selects DeprecationPhenotype based on a feature flag deprecation level.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-show/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-show/index.html new file mode 100644 index 000000000..2f1f430a2 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-show/index.html @@ -0,0 +1,115 @@ + + + + + Show + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Show

+

Does not differentiate deprecated feature flags from not deprecated ones.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-strikethrough/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-strikethrough/index.html new file mode 100644 index 000000000..46c6e6e25 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/-strikethrough/index.html @@ -0,0 +1,115 @@ + + + + + Strikethrough + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Strikethrough

+

Strikes feature flag name through.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/entries.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/entries.html new file mode 100644 index 000000000..6871fa87f --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/entries.html @@ -0,0 +1,76 @@ + + + + + entries + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

entries

+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

This method may be used to iterate over the enum entries.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/index.html new file mode 100644 index 000000000..3590e5141 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/index.html @@ -0,0 +1,232 @@ + + + + + DeprecationPhenotype + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

DeprecationPhenotype

+

UI representation of deprecated feature flags.

+
+
+
+
+
+

Entries

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Does not differentiate deprecated feature flags from not deprecated ones.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Strikes feature flag name through.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Removed feature flag from a list.

+
+
+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun interface Selector

Determines UI representation of feature flags based on their DeprecationLevel.

+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns a representation of an immutable list of all enum entries, in the order they're declared.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Returns an array containing the constants of this enum type, in the order they're declared.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/value-of.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/value-of.html new file mode 100644 index 000000000..23aab12d0 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/value-of.html @@ -0,0 +1,76 @@ + + + + + valueOf + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

valueOf

+
+

Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)

Throws

if this enum type has no constant with the specified name

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/values.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/values.html new file mode 100644 index 000000000..e134850f6 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-deprecation-phenotype/values.html @@ -0,0 +1,76 @@ + + + + + values + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

values

+
+

Returns an array containing the constants of this enum type, in the order they're declared.

This method may be used to iterate over the constants.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/configure.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/configure.html new file mode 100644 index 000000000..c838c52c1 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/configure.html @@ -0,0 +1,76 @@ + + + + + configure + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

configure

+
+
fun configure(laboratory: Laboratory, mainFactory: FeatureFactory, externalFactories: Map<String, FeatureFactory> = emptyMap())

Configures LaboratoryActivity with a default "Features" tab, where feature flags are taken from the mainFactory. Any additional tabs can be added in externalFactories.


Configures LaboratoryActivity with an input configuration.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/index.html new file mode 100644 index 000000000..37b779478 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/index.html @@ -0,0 +1,115 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Configures LaboratoryActivity with an input configuration.

fun configure(laboratory: Laboratory, mainFactory: FeatureFactory, externalFactories: Map<String, FeatureFactory> = emptyMap())

Configures LaboratoryActivity with a default "Features" tab, where feature flags are taken from the mainFactory. Any additional tabs can be added in externalFactories.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun start(context: Context)

Opens QA module. Configure needs to be called before you interact with LaboratoryActivity.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/start.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/start.html new file mode 100644 index 000000000..465f47c1b --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-companion/start.html @@ -0,0 +1,76 @@ + + + + + start + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

start

+
+
fun start(context: Context)

Opens QA module. Configure needs to be called before you interact with LaboratoryActivity.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/build.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/build.html new file mode 100644 index 000000000..644b4aa6e --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/build.html @@ -0,0 +1,76 @@ + + + + + build + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

build

+
+

Creates a new Configuration with provided parameters.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-alignment-selector.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-alignment-selector.html new file mode 100644 index 000000000..24d3fc7b8 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-alignment-selector.html @@ -0,0 +1,76 @@ + + + + + deprecationAlignmentSelector + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

deprecationAlignmentSelector

+
+

Sets how deprecated feature flags will be sorted in a displayed group.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-phenotype-selector.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-phenotype-selector.html new file mode 100644 index 000000000..639c9928f --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/deprecation-phenotype-selector.html @@ -0,0 +1,76 @@ + + + + + deprecationPhenotypeSelector + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

deprecationPhenotypeSelector

+
+

Sets how deprecated feature flags will be displayed to the user.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/index.html new file mode 100644 index 000000000..16efbed2d --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/index.html @@ -0,0 +1,145 @@ + + + + + BuildingStep + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

BuildingStep

+
interface BuildingStep

The final step of a fluent builder that can set optional parameters.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Creates a new Configuration with provided parameters.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets how deprecated feature flags will be sorted in a displayed group.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets how deprecated feature flags will be displayed to the user.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets how many offscreen feature sections will be kept in memory.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/offscreen-section-behavior.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/offscreen-section-behavior.html new file mode 100644 index 000000000..b9cb0bc32 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-building-step/offscreen-section-behavior.html @@ -0,0 +1,76 @@ + + + + + offscreenSectionBehavior + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

offscreenSectionBehavior

+
+

Sets how many offscreen feature sections will be kept in memory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/builder.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/builder.html new file mode 100644 index 000000000..ba8e65440 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/builder.html @@ -0,0 +1,76 @@ + + + + + builder + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

builder

+
+

Creates a builder that allows to customize Configuration.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/create.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/create.html new file mode 100644 index 000000000..125e04656 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/create.html @@ -0,0 +1,76 @@ + + + + + create + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

create

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/index.html new file mode 100644 index 000000000..5fbfc50df --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-companion/index.html @@ -0,0 +1,115 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Creates a builder that allows to customize Configuration.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/feature-factories.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/feature-factories.html new file mode 100644 index 000000000..d6c23698d --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/feature-factories.html @@ -0,0 +1,76 @@ + + + + + featureFactories + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

featureFactories

+
+

Sets feature factories. Each entry in this map will result in a separate tab in the QA module. Key is used as a tab name, and each tab displays all feature flags provided by FeatureFactory from value.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/index.html new file mode 100644 index 000000000..902143e26 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-feature-factories-step/index.html @@ -0,0 +1,100 @@ + + + + + FeatureFactoriesStep + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFactoriesStep

+

A step of a fluent builder that requires feature factories to proceed.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets feature factories. Each entry in this map will result in a separate tab in the QA module. Key is used as a tab name, and each tab displays all feature flags provided by FeatureFactory from value.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/index.html new file mode 100644 index 000000000..755696ce2 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/index.html @@ -0,0 +1,100 @@ + + + + + LaboratoryStep + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryStep

+
interface LaboratoryStep

A step of a fluent builder that requires Laboratory to proceed.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets laboratory. Its instance should share FeatureStorage instance with your application.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/laboratory.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/laboratory.html new file mode 100644 index 000000000..f7e51d6fb --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-laboratory-step/laboratory.html @@ -0,0 +1,76 @@ + + + + + laboratory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

laboratory

+
+

Sets laboratory. Its instance should share FeatureStorage instance with your application.

+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/-limited.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/-limited.html new file mode 100644 index 000000000..dcba68b11 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/-limited.html @@ -0,0 +1,76 @@ + + + + + Limited + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Limited

+
+
constructor(limit: Int)
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/index.html new file mode 100644 index 000000000..40c2faef7 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/index.html @@ -0,0 +1,119 @@ + + + + + Limited + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Limited

+

Number of sections is limited.

+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor(limit: Int)
+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val limit: Int
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/limit.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/limit.html new file mode 100644 index 000000000..a1c1638cf --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-limited/limit.html @@ -0,0 +1,76 @@ + + + + + limit + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

limit

+
+
val limit: Int
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-unlimited/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-unlimited/index.html new file mode 100644 index 000000000..27852fe67 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/-unlimited/index.html @@ -0,0 +1,80 @@ + + + + + Unlimited + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Unlimited

+

All sections are always kept in memory. This makes navigation smoother but might result in slower load time of the inspector.

+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/index.html new file mode 100644 index 000000000..fd1c4c0b5 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/-offscreen-sections-behavior/index.html @@ -0,0 +1,115 @@ + + + + + OffscreenSectionsBehavior + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

OffscreenSectionsBehavior

+

Behavior of feature sections that are not currently displayed.

Inheritors

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Number of sections is limited.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

All sections are always kept in memory. This makes navigation smoother but might result in slower load time of the inspector.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/index.html new file mode 100644 index 000000000..4f0535275 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-configuration/index.html @@ -0,0 +1,160 @@ + + + + + Configuration + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Configuration

+

Configuration data for QA module.

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface BuildingStep

The final step of a fluent builder that can set optional parameters.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

A step of a fluent builder that requires feature factories to proceed.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface LaboratoryStep

A step of a fluent builder that requires Laboratory to proceed.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Behavior of feature sections that are not currently displayed.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-laboratory-activity.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-laboratory-activity.html new file mode 100644 index 000000000..49870c31d --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/-laboratory-activity.html @@ -0,0 +1,76 @@ + + + + + LaboratoryActivity + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryActivity

+
+
constructor()
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/index.html new file mode 100644 index 000000000..fb9c5eeb9 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/-laboratory-activity/index.html @@ -0,0 +1,6262 @@ + + + + + LaboratoryActivity + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

LaboratoryActivity

+

Entry point for QA module that allows to interact with feature flags.

+
+
+
+
+
+

Constructors

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
constructor()
+
+
+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Configuration data for QA module.

+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
@get:NonNull
open override val lifecycle: Lifecycle
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
@get:NonNull
open override val viewModelStore: ViewModelStore
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun addContentView(p0: View, p1: ViewGroup.LayoutParams)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
override fun addOnNewIntentListener(@NonNull listener: Consumer<Intent>)
+
+
+
+
+ +
+ +
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
override fun addOnTrimMemoryListener(@NonNull listener: Consumer<Int>)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun bindService(p0: Intent, p1: ServiceConnection, p2: Int): Boolean
open override fun bindService(p0: Intent, p1: Int, p2: Executor, p3: ServiceConnection): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkCallingOrSelfPermission(p0: String): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkCallingOrSelfUriPermission(p0: Uri, p1: Int): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkCallingPermission(p0: String): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkCallingUriPermission(p0: Uri, p1: Int): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkCallingUriPermissions(p0: MutableList<Uri>, p1: Int): IntArray
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkPermission(p0: String, p1: Int, p2: Int): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkSelfPermission(p0: String): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkUriPermission(p0: Uri, p1: Int, p2: Int, p3: Int): Int
open override fun checkUriPermission(p0: Uri?, p1: String?, p2: String?, p3: Int, p4: Int, p5: Int): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun checkUriPermissions(p0: MutableList<Uri>, p1: Int, p2: Int, p3: Int): IntArray
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun clearWallpaper()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun closeContextMenu()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun closeOptionsMenu()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createAttributionContext(p0: String?): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createContext(p0: ContextParams): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createContextForSplit(p0: String): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createDeviceContext(p0: Int): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createDisplayContext(p0: Display): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createPackageContext(p0: String, p1: Int): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun createWindowContext(p0: Int, p1: Bundle?): Context
open override fun createWindowContext(p0: Display, p1: Int, p2: Bundle?): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun databaseList(): Array<String>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun deleteDatabase(p0: String): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun deleteFile(p0: String): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun deleteSharedPreferences(p0: String): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun dispatchKeyEvent(event: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun dispatchKeyShortcutEvent(event: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun dispatchTouchEvent(p0: MotionEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun dump(@NonNull p0: String, @Nullable p1: FileDescriptor?, @NonNull p2: PrintWriter, @Nullable p3: Array<String>?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun enforceCallingOrSelfPermission(p0: String, p1: String?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun enforceCallingOrSelfUriPermission(p0: Uri, p1: Int, p2: String)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun enforceCallingPermission(p0: String, p1: String?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun enforceCallingUriPermission(p0: Uri, p1: Int, p2: String)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun enforcePermission(p0: String, p1: Int, p2: Int, p3: String?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun enforceUriPermission(p0: Uri, p1: Int, p2: Int, p3: Int, p4: String)
open override fun enforceUriPermission(p0: Uri?, p1: String?, p2: String?, p3: Int, p4: Int, p5: Int, p6: String?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun fileList(): Array<String>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun <T : View> findViewById(@IdRes p0: Int): T
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun finish()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun finishActivity(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun finishAffinity()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun getActionBar(): ActionBar?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getApplicationContext(): Context
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getApplicationInfo(): ApplicationInfo
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getAssets(): AssetManager
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getAttributionTag(): String?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getCacheDir(): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getClassLoader(): ClassLoader
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getCodeCacheDir(): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun getColor(p0: Int): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getContentResolver(): ContentResolver
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun getCurrentFocus(): View?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getDatabasePath(p0: String): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getDataDir(): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getDeviceId(): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getDir(p0: String, p1: Int): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getDisplay(): Display?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getExternalCacheDir(): File?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getExternalCacheDirs(): Array<File>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getExternalFilesDir(p0: String?): File?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getExternalFilesDirs(p0: String): Array<File>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getExternalMediaDirs(): Array<File>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun <T : ComponentActivity.ExtraData> getExtraData(extraDataClass: Class<T>): T?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getFilesDir(): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getFileStreamPath(p0: String): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun getIntent(): Intent
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getMainExecutor(): Executor
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getMainLooper(): Looper
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getMenuInflater(): MenuInflater
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getNoBackupFilesDir(): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getObbDir(): File
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getObbDirs(): Array<File>
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getOpPackageName(): String
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getPackageCodePath(): String
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getPackageManager(): PackageManager
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getPackageName(): String
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getPackageResourcePath(): String
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getParams(): ContextParams?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun getReferrer(): Uri?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getResources(): Resources
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getSharedPreferences(p0: String, p1: Int): SharedPreferences
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun getString(p0: Int): String
fun getString(p0: Int, vararg p1: Any): String
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getSystemService(p0: String): Any
fun <T : Any> getSystemService(p0: Class<T>): T
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getSystemServiceName(p0: Class<*>): String?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun getTaskId(): Int
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getTheme(): Resources.Theme
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun getWallpaper(): Drawable
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun getWindow(): Window
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun grantUriPermission(p0: String, p1: Uri, p2: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun invalidateMenu()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun invalidateOptionsMenu()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun isDestroyed(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun isDeviceProtectedStorage(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun isFinishing(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun isImmersive(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun isRestricted(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun isTaskRoot(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun isUiContext(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun managedQuery(p0: Uri, p1: Array<String>, p2: String, p3: Array<String>, p4: String): Cursor
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun moveDatabaseFrom(p0: Context, p1: String): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun moveSharedPreferencesFrom(p0: Context, p1: String): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun navigateUpTo(p0: Intent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ + + +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onActionModeFinished(p0: ActionMode)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onActionModeStarted(p0: ActionMode)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun onActivityReenter(p0: Int, p1: Intent)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onAttachedToWindow()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onBackPressed()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onContentChanged()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun onCreate(p0: Bundle?, p1: PersistableBundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onCreatePanelMenu(p0: Int, @NonNull p1: Menu): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onCreatePanelView(p0: Int): View?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onCreateView(@NonNull p0: String, @NonNull p1: Context, @NonNull p2: AttributeSet): View?
open override fun onCreateView(@Nullable p0: View?, @NonNull p1: String, @NonNull p2: Context, @NonNull p3: AttributeSet): View?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onDetachedFromWindow()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onKeyDown(p0: Int, p1: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onKeyLongPress(p0: Int, p1: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onKeyMultiple(p0: Int, p1: Int, p2: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun onKeyShortcut(p0: Int, p1: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onKeyUp(p0: Int, p1: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onLowMemory()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
override fun onMenuItemSelected(p0: Int, @NonNull p1: MenuItem): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onMenuOpened(p0: Int, p1: Menu): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun onNavigateUp(): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onPanelClosed(p0: Int, @NonNull p1: Menu)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onPreparePanel(p0: Int, @Nullable p1: View?, @NonNull p2: Menu): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onSearchRequested(): Boolean
open override fun onSearchRequested(p0: SearchEvent?): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onStateNotSaved()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onTrimMemory(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun onWindowFocusChanged(p0: Boolean)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun openContextMenu(p0: View)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun openFileInput(p0: String): FileInputStream
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun openFileOutput(p0: String, p1: Int): FileOutputStream
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun openOptionsMenu()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun overrideActivityTransition(p0: Int, p1: Int, p2: Int)
open fun overrideActivityTransition(p0: Int, p1: Int, p2: Int, p3: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun overridePendingTransition(p0: Int, p1: Int)
open fun overridePendingTransition(p0: Int, p1: Int, p2: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun peekAvailableContext(): Context?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun peekWallpaper(): Drawable
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun recreate()
+
+
+
+
+ + + +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ + + +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun registerReceiver(p0: BroadcastReceiver?, p1: IntentFilter): Intent?
open override fun registerReceiver(p0: BroadcastReceiver?, p1: IntentFilter, p2: Int): Intent?
open override fun registerReceiver(p0: BroadcastReceiver?, p1: IntentFilter, p2: String?, p3: Handler?): Intent?
open override fun registerReceiver(p0: BroadcastReceiver?, p1: IntentFilter, p2: String?, p3: Handler?, p4: Int): Intent?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun removeDialog(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun removeMenuProvider(@NonNull p0: MenuProvider)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ + + +
+
+
+ + +
Link copied to clipboard
+
+
+
+
override fun removeOnTrimMemoryListener(@NonNull listener: Consumer<Int>)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun removeStickyBroadcast(p0: Intent)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun removeStickyBroadcastAsUser(p0: Intent, p1: UserHandle)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun reportFullyDrawn()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun <T : View> requireViewById(p0: Int): T & Any
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun revokeUriPermission(p0: Uri, p1: Int)
open override fun revokeUriPermission(p0: String, p1: Uri, p2: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendBroadcast(p0: Intent)
open override fun sendBroadcast(p0: Intent, p1: String?)
open override fun sendBroadcast(p0: Intent, p1: String?, p2: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendBroadcastAsUser(p0: Intent, p1: UserHandle)
open override fun sendBroadcastAsUser(p0: Intent, p1: UserHandle, p2: String?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendOrderedBroadcast(p0: Intent, p1: String?)
open override fun sendOrderedBroadcast(p0: Intent, p1: String?, p2: Bundle?)
open override fun sendOrderedBroadcast(p0: Intent, p1: String?, p2: BroadcastReceiver?, p3: Handler?, p4: Int, p5: String?, p6: Bundle?)
open override fun sendOrderedBroadcast(p0: Intent, p1: String?, p2: Bundle?, p3: BroadcastReceiver?, p4: Handler?, p5: Int, p6: String?, p7: Bundle?)
open override fun sendOrderedBroadcast(p0: Intent, p1: String?, p2: String?, p3: BroadcastReceiver?, p4: Handler?, p5: Int, p6: String?, p7: Bundle?)
open fun sendOrderedBroadcast(p0: Intent, p1: Int, p2: String?, p3: String?, p4: BroadcastReceiver?, p5: Handler?, p6: String?, p7: Bundle?, p8: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendOrderedBroadcastAsUser(p0: Intent, p1: UserHandle, p2: String?, p3: BroadcastReceiver?, p4: Handler?, p5: Int, p6: String?, p7: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendStickyBroadcast(p0: Intent)
open override fun sendStickyBroadcast(p0: Intent, p1: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendStickyBroadcastAsUser(p0: Intent, p1: UserHandle)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendStickyOrderedBroadcast(p0: Intent, p1: BroadcastReceiver?, p2: Handler?, p3: Int, p4: String?, p5: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun sendStickyOrderedBroadcastAsUser(p0: Intent, p1: UserHandle, p2: BroadcastReceiver?, p3: Handler?, p4: Int, p5: String?, p6: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setActionBar(p0: Toolbar?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun setContentView(p0: View)
open override fun setContentView(@LayoutRes p0: Int)
open override fun setContentView(p0: View, p1: ViewGroup.LayoutParams)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ + + + + +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setImmersive(p0: Boolean)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setIntent(p0: Intent)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setLocusContext(p0: LocusId?, p1: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun setProgress(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun setResult(p0: Int)
fun setResult(p0: Int, p1: Intent)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setSupportProgress(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setTheme(p0: Resources.Theme?)
open override fun setTheme(@StyleRes p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setTitle(p0: CharSequence)
open fun setTitle(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setTitleColor(p0: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setTurnScreenOn(p0: Boolean)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun setVisible(p0: Boolean)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun setWallpaper(p0: Bitmap)
open override fun setWallpaper(p0: InputStream)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun showAssist(p0: Bundle): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun showDialog(p0: Int)
fun showDialog(p0: Int, p1: Bundle): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startActivities(p0: Array<Intent>)
open override fun startActivities(p0: Array<Intent>, p1: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startActivity(p0: Intent)
open override fun startActivity(p0: Intent, p1: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startActivityForResult(@NonNull p0: Intent, p1: Int)
open override fun startActivityForResult(@NonNull p0: Intent, p1: Int, @Nullable p2: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun startActivityFromChild(p0: Activity, p1: Intent, p2: Int)
open fun startActivityFromChild(p0: Activity, p1: Intent, p2: Int, p3: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startInstrumentation(p0: ComponentName, p1: String?, p2: Bundle?): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startIntentSender(p0: IntentSender, p1: Intent?, p2: Int, p3: Int, p4: Int)
open override fun startIntentSender(p0: IntentSender, p1: Intent?, p2: Int, p3: Int, p4: Int, p5: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startIntentSenderForResult(@NonNull p0: IntentSender, p1: Int, @Nullable p2: Intent?, p3: Int, p4: Int, p5: Int)
open override fun startIntentSenderForResult(@NonNull p0: IntentSender, p1: Int, @Nullable p2: Intent?, p3: Int, p4: Int, p5: Int, @Nullable p6: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun startIntentSenderFromChild(p0: Activity, p1: IntentSender, p2: Int, p3: Intent, p4: Int, p5: Int, p6: Int)
open fun startIntentSenderFromChild(p0: Activity, p1: IntentSender, p2: Int, p3: Intent, p4: Int, p5: Int, p6: Int, p7: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun startIntentSenderFromFragment(@NonNull p0: Fragment, @NonNull p1: IntentSender, p2: Int, @Nullable p3: Intent?, p4: Int, p5: Int, p6: Int, @Nullable p7: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun startLockTask()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun startSearch(p0: String?, p1: Boolean, p2: Bundle?, p3: Boolean)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun startService(p0: Intent): ComponentName?
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun stopLockTask()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun stopService(p0: Intent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun superDispatchKeyEvent(event: KeyEvent): Boolean
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun supportInvalidateOptionsMenu()
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun takeKeyEvents(p0: Boolean)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open fun triggerSearch(p0: String, p1: Bundle?)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun unbindService(p0: ServiceConnection)
+
+
+
+
+ + + +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun unregisterReceiver(p0: BroadcastReceiver)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+ +
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open override fun updateServiceGroup(p0: ServiceConnection, p1: Int, p2: Int)
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/io.mehow.laboratory.inspector/index.html b/api/laboratory/inspector/io.mehow.laboratory.inspector/index.html new file mode 100644 index 000000000..2039e20a6 --- /dev/null +++ b/api/laboratory/inspector/io.mehow.laboratory.inspector/index.html @@ -0,0 +1,129 @@ + + + + + io.mehow.laboratory.inspector + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Package-level declarations

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Alignment of deprecated feature flags in a list.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

UI representation of deprecated feature flags.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Entry point for QA module that allows to interact with feature flags.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/inspector/navigation.html b/api/laboratory/inspector/navigation.html new file mode 100644 index 000000000..b634800a6 --- /dev/null +++ b/api/laboratory/inspector/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/laboratory/runtime/index.html b/api/laboratory/runtime/index.html new file mode 100644 index 000000000..fe46dc8bc --- /dev/null +++ b/api/laboratory/runtime/index.html @@ -0,0 +1,95 @@ + + + + + runtime + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

runtime

+
+

Packages

+
+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-io-call/index.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-io-call/index.html new file mode 100644 index 000000000..7be085c9c --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-io-call/index.html @@ -0,0 +1,80 @@ + + + + + BlockingIoCall + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

BlockingIoCall

+

Opt-in annotation denoting that the used function can potentially block a calling thread with I/O operations.

+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/clear.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/clear.html new file mode 100644 index 000000000..97b8a417d --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/clear.html @@ -0,0 +1,76 @@ + + + + + clear + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

clear

+
+
fun clear(): Boolean

Removes all stored feature flag options. Warning – this call can block the calling thread.

Return

true if the option was set successfully, false otherwise.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment-is.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment-is.html new file mode 100644 index 000000000..880ba5d90 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment-is.html @@ -0,0 +1,76 @@ + + + + + experimentIs + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

experimentIs

+
+
fun <T : Feature<out T>> experimentIs(option: T): Boolean

Checks if a Feature is set to the input option. Warning – this call can block the calling thread.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment.html new file mode 100644 index 000000000..cb44fcf11 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/experiment.html @@ -0,0 +1,76 @@ + + + + + experiment + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

experiment

+
+
inline fun <T : Feature<out T>> experiment(): T
fun <T : Feature<out T>> experiment(feature: Class<out T>): T

Returns the current option of the input Feature. Warning – this call can block the calling thread.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/index.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/index.html new file mode 100644 index 000000000..a57f885a2 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/index.html @@ -0,0 +1,160 @@ + + + + + BlockingLaboratory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

BlockingLaboratory

+

A blocking equivalent of Laboratory.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun clear(): Boolean

Removes all stored feature flag options. Warning – this call can block the calling thread.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
inline fun <T : Feature<out T>> experiment(): T
fun <T : Feature<out T>> experiment(feature: Class<out T>): T

Returns the current option of the input Feature. Warning – this call can block the calling thread.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun <T : Feature<out T>> experimentIs(option: T): Boolean

Checks if a Feature is set to the input option. Warning – this call can block the calling thread.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun <T : Feature<*>> setOption(option: T): Boolean

Sets a Feature to have the input option. Warning – this call can block the calling thread.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun <T : Feature<*>> setOptions(vararg options: T): Boolean
fun <T : Feature<*>> setOptions(options: Collection<T>): Boolean

Sets Features to have the input options. If options contains more than one option for the same feature flag, the last one should be applied. Warning – this call can block the calling thread.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-option.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-option.html new file mode 100644 index 000000000..14e35078a --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-option.html @@ -0,0 +1,76 @@ + + + + + setOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

setOption

+
+
fun <T : Feature<*>> setOption(option: T): Boolean

Sets a Feature to have the input option. Warning – this call can block the calling thread.

Return

true if the option was set successfully, false otherwise.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-options.html b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-options.html new file mode 100644 index 000000000..3101aa0ed --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-blocking-laboratory/set-options.html @@ -0,0 +1,76 @@ + + + + + setOptions + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

setOptions

+
+
fun <T : Feature<*>> setOptions(vararg options: T): Boolean
fun <T : Feature<*>> setOptions(options: Collection<T>): Boolean

Sets Features to have the input options. If options contains more than one option for the same feature flag, the last one should be applied. Warning – this call can block the calling thread.

Return

true if the option was set successfully, false otherwise.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/-companion/index.html b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/-companion/index.html new file mode 100644 index 000000000..b24cba9ee --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/-companion/index.html @@ -0,0 +1,80 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/create.html b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/create.html new file mode 100644 index 000000000..e9a363603 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/create.html @@ -0,0 +1,76 @@ + + + + + create + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

create

+
+
abstract fun <T : Feature<out T>> create(feature: T): Feature<*>?

Returns override for a default option or null if there should be no override.

Warning – returned default option must be of the same type as feature. Otherwise it will throw an exception.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/index.html b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/index.html new file mode 100644 index 000000000..bfcdc09ab --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/index.html @@ -0,0 +1,134 @@ + + + + + DefaultOptionFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

DefaultOptionFactory

+

Factory that allows to override default feature flag option used by Laboratory.

See also

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract fun <T : Feature<out T>> create(feature: T): Feature<*>?

Returns override for a default option or null if there should be no override.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open operator fun plus(factory: DefaultOptionFactory): DefaultOptionFactory

Creates a new DefaultOptionFactory that will first look for a default value in this factory and then in the other factory.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/plus.html b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/plus.html new file mode 100644 index 000000000..f6152d4b1 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-default-option-factory/plus.html @@ -0,0 +1,76 @@ + + + + + plus + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

plus

+
+
open operator fun plus(factory: DefaultOptionFactory): DefaultOptionFactory

Creates a new DefaultOptionFactory that will first look for a default value in this factory and then in the other factory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/-companion/index.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/-companion/index.html new file mode 100644 index 000000000..b2fb17f50 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/-companion/index.html @@ -0,0 +1,80 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/create.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/create.html new file mode 100644 index 000000000..0c9b70711 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/create.html @@ -0,0 +1,76 @@ + + + + + create + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

create

+
+
abstract fun create(): Set<Class<out Feature<*>>>

Returns set of all available feature flags.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/index.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/index.html new file mode 100644 index 000000000..927707930 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/index.html @@ -0,0 +1,134 @@ + + + + + FeatureFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureFactory

+
interface FeatureFactory

Factory that should provide all available feature flags. There shouldn't be any need to use it in a regular application code. Its main purpose is for QA inspection module.

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract fun create(): Set<Class<out Feature<*>>>

Returns set of all available feature flags.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open operator fun plus(factory: FeatureFactory): FeatureFactory

Creates a new FeatureFactory that will return a combined set of this factory and the other factory.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/plus.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/plus.html new file mode 100644 index 000000000..9c7cd946e --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-factory/plus.html @@ -0,0 +1,76 @@ + + + + + plus + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

plus

+
+
open operator fun plus(factory: FeatureFactory): FeatureFactory

Creates a new FeatureFactory that will return a combined set of this factory and the other factory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/in-memory.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/in-memory.html new file mode 100644 index 000000000..9cad52171 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/in-memory.html @@ -0,0 +1,76 @@ + + + + + inMemory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

inMemory

+
+

Creates FeatureStorage that saves feature flags in app's memory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/index.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/index.html new file mode 100644 index 000000000..c5a2569bc --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/index.html @@ -0,0 +1,115 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Creates FeatureStorage that saves feature flags in app's memory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
fun sourced(localSource: FeatureStorage, remoteSources: Map<String, FeatureStorage>): FeatureStorage

Creates FeatureStorage that is aware of different sources for feature flag values. For example, the following code will be able to produce values for local, Firebase and Aws sources, and will automatically switch reads based on currently selected sources for feature flags.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/sourced.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/sourced.html new file mode 100644 index 000000000..a4e25ba7d --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/-companion/sourced.html @@ -0,0 +1,76 @@ + + + + + sourced + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

sourced

+
+
fun sourced(localSource: FeatureStorage, remoteSources: Map<String, FeatureStorage>): FeatureStorage

Creates FeatureStorage that is aware of different sources for feature flag values. For example, the following code will be able to produce values for local, Firebase and Aws sources, and will automatically switch reads based on currently selected sources for feature flags.

FeatureStorage.sourced(
localSource = FeatureStorage.inMemory(),
remoteSources = mapOf(
"Firebase" to FeatureStorage.inMemory(),
"Aws" to FeatureStorage.inMemory(),
),
)

In order to connect remote sources with sources of feature flag sources they need to match their names. If you use Gradle plugin, you should not use this method as a more specialised factory method will be generated for you, that will make sure that all remote sources are configured.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/clear.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/clear.html new file mode 100644 index 000000000..aee8dd204 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/clear.html @@ -0,0 +1,76 @@ + + + + + clear + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

clear

+
+
abstract suspend fun clear(): Boolean

Removes all stored feature flag options.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/get-feature-name.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/get-feature-name.html new file mode 100644 index 000000000..fa2d7d69e --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/get-feature-name.html @@ -0,0 +1,76 @@ + + + + + getFeatureName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

getFeatureName

+
+
abstract suspend fun getFeatureName(feature: Class<out Feature<*>>): String?

Returns the current value of a selected feature flag name. If feature flag is not available, it should return null.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/index.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/index.html new file mode 100644 index 000000000..dda988334 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/index.html @@ -0,0 +1,194 @@ + + + + + FeatureStorage + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureStorage

+
interface FeatureStorage

Persistence mechanism for feature flags.

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract suspend fun clear(): Boolean

Removes all stored feature flag options.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract suspend fun getFeatureName(feature: Class<out Feature<*>>): String?

Returns the current value of a selected feature flag name. If feature flag is not available, it should return null.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract fun observeFeatureName(feature: Class<out Feature<*>>): Flow<String?>

Observes changes to currently selected feature flag name. If feature flag is not available, it should emit null.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open suspend fun setOption(option: Feature<*>): Boolean

Sets a Feature to have the input option.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract suspend fun setOptions(vararg options: Feature<*>): Boolean
open suspend fun setOptions(options: Collection<Feature<*>>): Boolean

Sets Features to have the input options. If options contains more than one value for the same feature flag, the last one should be applied.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Allows implementation to handle default option overrides provided via factory if necessary.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/observe-feature-name.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/observe-feature-name.html new file mode 100644 index 000000000..599e9f688 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/observe-feature-name.html @@ -0,0 +1,76 @@ + + + + + observeFeatureName + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

observeFeatureName

+
+
abstract fun observeFeatureName(feature: Class<out Feature<*>>): Flow<String?>

Observes changes to currently selected feature flag name. If feature flag is not available, it should emit null.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-option.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-option.html new file mode 100644 index 000000000..143c1dfa1 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-option.html @@ -0,0 +1,76 @@ + + + + + setOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

setOption

+
+
open suspend fun setOption(option: Feature<*>): Boolean

Sets a Feature to have the input option.

Return

true if the value was set successfully, false otherwise.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-options.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-options.html new file mode 100644 index 000000000..b06e9cba1 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/set-options.html @@ -0,0 +1,76 @@ + + + + + setOptions + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

setOptions

+
+
abstract suspend fun setOptions(vararg options: Feature<*>): Boolean
open suspend fun setOptions(options: Collection<Feature<*>>): Boolean

Sets Features to have the input options. If options contains more than one value for the same feature flag, the last one should be applied.

Return

true if the value was set successfully, false otherwise.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/with-default-option-factory.html b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/with-default-option-factory.html new file mode 100644 index 000000000..b9a3dc891 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature-storage/with-default-option-factory.html @@ -0,0 +1,76 @@ + + + + + withDefaultOptionFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

withDefaultOptionFactory

+
+

Allows implementation to handle default option overrides provided via factory if necessary.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature/default-option.html b/api/laboratory/runtime/io.mehow.laboratory/-feature/default-option.html new file mode 100644 index 000000000..a29672781 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature/default-option.html @@ -0,0 +1,76 @@ + + + + + defaultOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

defaultOption

+
+
abstract val defaultOption: T

Determines which option is a default for this feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature/description.html b/api/laboratory/runtime/io.mehow.laboratory/-feature/description.html new file mode 100644 index 000000000..b00c1b220 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature/description.html @@ -0,0 +1,76 @@ + + + + + description + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

description

+
+

Description of the feature flag that can be used for more contextual information. Markdown formatted links will be picked up by the QA module and represented as hyperlinks.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature/index.html b/api/laboratory/runtime/io.mehow.laboratory/-feature/index.html new file mode 100644 index 000000000..ab9656dd5 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature/index.html @@ -0,0 +1,179 @@ + + + + + Feature + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Feature

+
interface Feature<T : Feature<T>, Enum<T>> : Comparable<T>

A feature flag that has one active option. Options are selected by interaction of this interface with Laboratory. Feature flag is a enum that implements this interface.

Warning: Enum values cannot individually override any functions. Otherwise serialization, and consequentially discovery of a selection option, will not work as it is based on a class name.

+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract val defaultOption: T

Determines which option is a default for this feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Description of the feature flag that can be used for more contextual information. Markdown formatted links will be picked up by the QA module and represented as hyperlinks.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract val name: String

A name of an option that should uniquely identify it within this feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open val source: Class<out Feature<*>>?

Source of feature flag values. When null it is assumed that the feature flag has only local source of values. Source is also a feature flag, which means it can be controlled by Laboratory as well. By convention, if this property is not null, one of the source values should be Local. For example, the following code will result in a flag that can be controlled by local, Firebase or Aws source.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Option of another feature flag that controls value of this child flag. When supervisor feature flag has an option different from this value then the child does not produce values other than the default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised.

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract operator fun compareTo(other: T): Int
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature/name.html b/api/laboratory/runtime/io.mehow.laboratory/-feature/name.html new file mode 100644 index 000000000..50f49f17e --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature/name.html @@ -0,0 +1,76 @@ + + + + + name + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

name

+
+
abstract val name: String

A name of an option that should uniquely identify it within this feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature/source.html b/api/laboratory/runtime/io.mehow.laboratory/-feature/source.html new file mode 100644 index 000000000..b273d0f4f --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature/source.html @@ -0,0 +1,76 @@ + + + + + source + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

source

+
+
open val source: Class<out Feature<*>>?

Source of feature flag values. When null it is assumed that the feature flag has only local source of values. Source is also a feature flag, which means it can be controlled by Laboratory as well. By convention, if this property is not null, one of the source values should be Local. For example, the following code will result in a flag that can be controlled by local, Firebase or Aws source.

enum class SomeFeature : Feature<SomeFeature> {
FirstValue,
SecondValue,
;

override val defaultOption get() = FirstValue

override val source = Source::class.java

enum class Source : Feature<Source> {
Local,
Firebase,
Aws,
;

override val defaultOption get() = Local
}
}
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-feature/supervisor-option.html b/api/laboratory/runtime/io.mehow.laboratory/-feature/supervisor-option.html new file mode 100644 index 000000000..f85205680 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-feature/supervisor-option.html @@ -0,0 +1,76 @@ + + + + + supervisorOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

supervisorOption

+
+

Option of another feature flag that controls value of this child flag. When supervisor feature flag has an option different from this value then the child does not produce values other than the default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/build.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/build.html new file mode 100644 index 000000000..892afd61a --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/build.html @@ -0,0 +1,76 @@ + + + + + build + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

build

+
+
abstract fun build(): Laboratory

Creates a new Laboratory with provided parameters.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/default-option-factory.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/default-option-factory.html new file mode 100644 index 000000000..651232092 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/default-option-factory.html @@ -0,0 +1,76 @@ + + + + + defaultOptionFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

defaultOptionFactory

+
+

Sets a factory that can provide default options override.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/index.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/index.html new file mode 100644 index 000000000..e5af0cb55 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-building-step/index.html @@ -0,0 +1,115 @@ + + + + + BuildingStep + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

BuildingStep

+
interface BuildingStep

The final step of a fluent builder that can set optional parameters.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract fun build(): Laboratory

Creates a new Laboratory with provided parameters.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets a factory that can provide default options override.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/builder.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/builder.html new file mode 100644 index 000000000..abc13d278 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/builder.html @@ -0,0 +1,76 @@ + + + + + builder + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

builder

+
+

Creates a builder that allows to customize Laboratory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/create.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/create.html new file mode 100644 index 000000000..46b915ada --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/create.html @@ -0,0 +1,76 @@ + + + + + create + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

create

+
+

Creates Laboratory with a provided storage.

Parameters

storage

FeatureStorage delegate that will persist all feature flags.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/in-memory.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/in-memory.html new file mode 100644 index 000000000..92b60caa3 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/in-memory.html @@ -0,0 +1,76 @@ + + + + + inMemory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

inMemory

+
+

Creates Laboratory with an in-memory persistence mechanism.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/index.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/index.html new file mode 100644 index 000000000..5e5965119 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-companion/index.html @@ -0,0 +1,130 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Creates a builder that allows to customize Laboratory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Creates Laboratory with a provided storage.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Creates Laboratory with an in-memory persistence mechanism.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/feature-storage.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/feature-storage.html new file mode 100644 index 000000000..bb2dadbf1 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/feature-storage.html @@ -0,0 +1,76 @@ + + + + + featureStorage + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

featureStorage

+
+

Sets a feature storage that will be used by Laboratory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/index.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/index.html new file mode 100644 index 000000000..42577d72b --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/-feature-storage-step/index.html @@ -0,0 +1,100 @@ + + + + + FeatureStorageStep + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

FeatureStorageStep

+

A step of a fluent builder that requires FeatureStorage to proceed.

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Sets a feature storage that will be used by Laboratory.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/blocking.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/blocking.html new file mode 100644 index 000000000..bf779667f --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/blocking.html @@ -0,0 +1,76 @@ + + + + + blocking + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

blocking

+
+

An entry point for blocking API.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/clear.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/clear.html new file mode 100644 index 000000000..8560dfdf6 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/clear.html @@ -0,0 +1,76 @@ + + + + + clear + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

clear

+
+
suspend fun clear(): Boolean

Removes all stored feature flag options.

Return

true if the option was set successfully, false otherwise.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment-is.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment-is.html new file mode 100644 index 000000000..afd958e6d --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment-is.html @@ -0,0 +1,76 @@ + + + + + experimentIs + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

experimentIs

+
+
suspend fun <T : Feature<out T>> experimentIs(option: T): Boolean

Checks if a Feature is set to the input option.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment.html new file mode 100644 index 000000000..05594f0d8 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/experiment.html @@ -0,0 +1,76 @@ + + + + + experiment + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

experiment

+
+
inline suspend fun <T : Feature<out T>> experiment(): T
suspend fun <T : Feature<out T>> experiment(feature: Class<out T>): T

Returns the current option of the input Feature.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/index.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/index.html new file mode 100644 index 000000000..c3bf2a366 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/index.html @@ -0,0 +1,239 @@ + + + + + Laboratory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Laboratory

+

High-level API for interaction with feature flags. It allows to read and write their options.

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface BuildingStep

The final step of a fluent builder that can set optional parameters.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

A step of a fluent builder that requires FeatureStorage to proceed.

+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

An entry point for blocking API.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
suspend fun clear(): Boolean

Removes all stored feature flag options.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
inline suspend fun <T : Feature<out T>> experiment(): T
suspend fun <T : Feature<out T>> experiment(feature: Class<out T>): T

Returns the current option of the input Feature.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
suspend fun <T : Feature<out T>> experimentIs(option: T): Boolean

Checks if a Feature is set to the input option.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
inline fun <T : Feature<out T>> observe(): Flow<T>
fun <T : Feature<out T>> observe(feature: Class<out T>): Flow<T>

Observes any changes to the input Feature.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
suspend fun <T : Feature<*>> setOption(option: T): Boolean

Sets a Feature to have the input option.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
suspend fun <T : Feature<*>> setOptions(vararg options: T): Boolean
suspend fun <T : Feature<*>> setOptions(options: Collection<T>): Boolean

Sets Features to have the input options. If options contains more than one option for the same feature flag, the last one should be applied.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/observe.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/observe.html new file mode 100644 index 000000000..c12410a77 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/observe.html @@ -0,0 +1,76 @@ + + + + + observe + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

observe

+
+
inline fun <T : Feature<out T>> observe(): Flow<T>
fun <T : Feature<out T>> observe(feature: Class<out T>): Flow<T>

Observes any changes to the input Feature.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-option.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-option.html new file mode 100644 index 000000000..0ebe8a5b6 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-option.html @@ -0,0 +1,76 @@ + + + + + setOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

setOption

+
+
suspend fun <T : Feature<*>> setOption(option: T): Boolean

Sets a Feature to have the input option.

Return

true if the option was set successfully, false otherwise.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-options.html b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-options.html new file mode 100644 index 000000000..81b06f406 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-laboratory/set-options.html @@ -0,0 +1,76 @@ + + + + + setOptions + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

setOptions

+
+
suspend fun <T : Feature<*>> setOptions(vararg options: T): Boolean
suspend fun <T : Feature<*>> setOptions(options: Collection<T>): Boolean

Sets Features to have the input options. If options contains more than one option for the same feature flag, the last one should be applied.

Return

true if the option was set successfully, false otherwise.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-option-factory/-companion/index.html b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/-companion/index.html new file mode 100644 index 000000000..5bb2162e8 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/-companion/index.html @@ -0,0 +1,80 @@ + + + + + Companion + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Companion

+
object Companion
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-option-factory/create.html b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/create.html new file mode 100644 index 000000000..b95355efd --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/create.html @@ -0,0 +1,76 @@ + + + + + create + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

create

+
+
abstract fun create(key: String, name: String): Feature<*>?

Returns a feature matching class name and option name or null if no match is found.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-option-factory/index.html b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/index.html new file mode 100644 index 000000000..df3d436c2 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/index.html @@ -0,0 +1,134 @@ + + + + + OptionFactory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

OptionFactory

+
interface OptionFactory

Factory that returns a matching option.

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
object Companion
+
+
+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
abstract fun create(key: String, name: String): Feature<*>?

Returns a feature matching class name and option name or null if no match is found.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
open operator fun plus(factory: OptionFactory): OptionFactory

Creates a new OptionFactory that will first look for an option in this factory and then in the other factory.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/-option-factory/plus.html b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/plus.html new file mode 100644 index 000000000..8a6437eaf --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/-option-factory/plus.html @@ -0,0 +1,76 @@ + + + + + plus + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

plus

+
+
open operator fun plus(factory: OptionFactory): OptionFactory

Creates a new OptionFactory that will first look for an option in this factory and then in the other factory.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/default-option.html b/api/laboratory/runtime/io.mehow.laboratory/default-option.html new file mode 100644 index 000000000..df4823292 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/default-option.html @@ -0,0 +1,76 @@ + + + + + defaultOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

defaultOption

+
+
val <T : Feature<out T>> Class<out T>.defaultOption: T

Default option of a feature flag.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/description.html b/api/laboratory/runtime/io.mehow.laboratory/description.html new file mode 100644 index 000000000..4c5d1058e --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/description.html @@ -0,0 +1,76 @@ + + + + + description + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

description

+
+

Description of a feature flag.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/index.html b/api/laboratory/runtime/io.mehow.laboratory/index.html new file mode 100644 index 000000000..891d77143 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/index.html @@ -0,0 +1,283 @@ + + + + + io.mehow.laboratory + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Package-level declarations

+
+
+
+
+
+

Types

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+

Opt-in annotation denoting that the used function can potentially block a calling thread with I/O operations.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

A blocking equivalent of Laboratory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Factory that allows to override default feature flag option used by Laboratory.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface Feature<T : Feature<T>, Enum<T>> : Comparable<T>

A feature flag that has one active option. Options are selected by interaction of this interface with Laboratory. Feature flag is a enum that implements this interface.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface FeatureFactory

Factory that should provide all available feature flags. There shouldn't be any need to use it in a regular application code. Its main purpose is for QA inspection module.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface FeatureStorage

Persistence mechanism for feature flags.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

High-level API for interaction with feature flags. It allows to read and write their options.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
interface OptionFactory

Factory that returns a matching option.

+
+
+
+
+
+
+
+

Properties

+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+
val <T : Feature<out T>> Class<out T>.defaultOption: T

Default option of a feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Description of a feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
val <T : Feature<out T>> Class<out T>.options: Array<out T>

All available options of a feature flag.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+
val Class<out Feature<*>>.source: Class<out Feature<*>>?

Source of feature flag values.

+
+
+
+
+ +
+
+
+ + +
Link copied to clipboard
+
+
+
+

Supervisor of a feature flag.

+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/options.html b/api/laboratory/runtime/io.mehow.laboratory/options.html new file mode 100644 index 000000000..c072c08cb --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/options.html @@ -0,0 +1,76 @@ + + + + + options + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

options

+
+
val <T : Feature<out T>> Class<out T>.options: Array<out T>

All available options of a feature flag.

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/source.html b/api/laboratory/runtime/io.mehow.laboratory/source.html new file mode 100644 index 000000000..fe24e41d3 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/source.html @@ -0,0 +1,76 @@ + + + + + source + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

source

+
+
val Class<out Feature<*>>.source: Class<out Feature<*>>?

Source of feature flag values.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/io.mehow.laboratory/supervisor-option.html b/api/laboratory/runtime/io.mehow.laboratory/supervisor-option.html new file mode 100644 index 000000000..2af0b3792 --- /dev/null +++ b/api/laboratory/runtime/io.mehow.laboratory/supervisor-option.html @@ -0,0 +1,76 @@ + + + + + supervisorOption + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

supervisorOption

+
+

Supervisor of a feature flag.

See also

+
+ +
+
+
+ + + diff --git a/api/laboratory/runtime/navigation.html b/api/laboratory/runtime/navigation.html new file mode 100644 index 000000000..b634800a6 --- /dev/null +++ b/api/laboratory/runtime/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/laboratory/shared-preferences/index.html b/api/laboratory/shared-preferences/index.html new file mode 100644 index 000000000..2cde3dbd0 --- /dev/null +++ b/api/laboratory/shared-preferences/index.html @@ -0,0 +1,95 @@ + + + + + shared-preferences + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

shared-preferences

+
+

Packages

+
+
+
+
+
+ + +
Link copied to clipboard
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/index.html b/api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/index.html new file mode 100644 index 000000000..43a658a4f --- /dev/null +++ b/api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/index.html @@ -0,0 +1,99 @@ + + + + + io.mehow.laboratory.sharedpreferences + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

Package-level declarations

+
+
+
+
+
+

Functions

+
+
+
+
+ + +
Link copied to clipboard
+
+ +
+
+
+
+
+
+
+ +
+
+
+ + + diff --git a/api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/shared-preferences.html b/api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/shared-preferences.html new file mode 100644 index 000000000..4d2933dae --- /dev/null +++ b/api/laboratory/shared-preferences/io.mehow.laboratory.sharedpreferences/shared-preferences.html @@ -0,0 +1,76 @@ + + + + + sharedPreferences + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+

sharedPreferences

+
+ +
+ +
+
+
+ + + diff --git a/api/laboratory/shared-preferences/navigation.html b/api/laboratory/shared-preferences/navigation.html new file mode 100644 index 000000000..b634800a6 --- /dev/null +++ b/api/laboratory/shared-preferences/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/navigation.html b/api/navigation.html new file mode 100644 index 000000000..d1afcf2e5 --- /dev/null +++ b/api/navigation.html @@ -0,0 +1,412 @@ +
+ +
+
+ generator +
+
+ +
+ +
+ + + + + +
+ +
+
+ +
+
+ Public +
+
+
+
+ Internal +
+
+
+
+
+
+ +
+ + + +
+ +
+
+ Warning +
+
+
+
+ Error +
+
+
+
+ Hidden +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + + +
+
+
+
+ inspector +
+
+ +
+ +
+
+ Selector +
+
+
+
+ Regular +
+
+
+
+ Bottom +
+
+
+
+ +
+
+ Selector +
+
+
+
+ Show +
+
+
+ +
+
+
+ Hide +
+
+
+
+ +
+
+ Companion +
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+ +
+
+ +
+
+ Limited +
+
+
+
+ Unlimited +
+
+
+
+
+
+
+
+
+ runtime +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ Companion +
+
+
+
+ +
+
+
+ Feature +
+
+
+ +
+
+ Companion +
+
+
+
+ +
+
+ Companion +
+
+
+
+ +
+ +
+
+
+ Companion +
+
+ +
+
+ +
+
+ Companion +
+
+
+
+
+ options +
+
+
+
+ source +
+
+ +
+
+ +
diff --git a/api/package-list b/api/package-list new file mode 100644 index 000000000..d2c671ed3 --- /dev/null +++ b/api/package-list @@ -0,0 +1,15 @@ +$dokka.format:html-v1 +$dokka.linkExtension:html + +module:data-store +io.mehow.laboratory.datastore +module:generator +io.mehow.laboratory.generator +module:gradle-plugin +io.mehow.laboratory.gradle +module:inspector +io.mehow.laboratory.inspector +module:runtime +io.mehow.laboratory +module:shared-preferences +io.mehow.laboratory.sharedpreferences diff --git a/api/scripts/clipboard.js b/api/scripts/clipboard.js new file mode 100644 index 000000000..7a4f33c59 --- /dev/null +++ b/api/scripts/clipboard.js @@ -0,0 +1,56 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +window.addEventListener('load', () => { + document.querySelectorAll('span.copy-icon').forEach(element => { + element.addEventListener('click', (el) => copyElementsContentToClipboard(element)); + }) + + document.querySelectorAll('span.anchor-icon').forEach(element => { + element.addEventListener('click', (el) => { + if(element.hasAttribute('pointing-to')){ + const location = hrefWithoutCurrentlyUsedAnchor() + '#' + element.getAttribute('pointing-to') + copyTextToClipboard(element, location) + } + }); + }) +}) + +const copyElementsContentToClipboard = (element) => { + const selection = window.getSelection(); + const range = document.createRange(); + range.selectNodeContents(element.parentNode.parentNode); + selection.removeAllRanges(); + selection.addRange(range); + + copyAndShowPopup(element, () => selection.removeAllRanges()) +} + +const copyTextToClipboard = (element, text) => { + var textarea = document.createElement("textarea"); + textarea.textContent = text; + textarea.style.position = "fixed"; + document.body.appendChild(textarea); + textarea.select(); + + copyAndShowPopup(element, () => document.body.removeChild(textarea)) +} + +const copyAndShowPopup = (element, after) => { + try { + document.execCommand('copy'); + element.nextElementSibling.classList.add('active-popup'); + setTimeout(() => { + element.nextElementSibling.classList.remove('active-popup'); + }, 1200); + } catch (e) { + console.error('Failed to write to clipboard:', e) + } + finally { + if(after) after() + } +} + +const hrefWithoutCurrentlyUsedAnchor = () => window.location.href.split('#')[0] + diff --git a/api/scripts/main.js b/api/scripts/main.js new file mode 100644 index 000000000..ba6c34739 --- /dev/null +++ b/api/scripts/main.js @@ -0,0 +1,44 @@ +(()=>{var e={8527:e=>{e.exports=''},5570:e=>{e.exports=''},107:e=>{e.exports=''},7224:e=>{e.exports=''},538:e=>{e.exports=''},1924:(e,n,t)=>{"use strict";var r=t(210),o=t(5559),i=o(r("String.prototype.indexOf"));e.exports=function(e,n){var t=r(e,!!n);return"function"==typeof t&&i(e,".prototype.")>-1?o(t):t}},5559:(e,n,t)=>{"use strict";var r=t(8612),o=t(210),i=o("%Function.prototype.apply%"),a=o("%Function.prototype.call%"),l=o("%Reflect.apply%",!0)||r.call(a,i),c=o("%Object.getOwnPropertyDescriptor%",!0),u=o("%Object.defineProperty%",!0),s=o("%Math.max%");if(u)try{u({},"a",{value:1})}catch(e){u=null}e.exports=function(e){var n=l(r,a,arguments);if(c&&u){var t=c(n,"length");t.configurable&&u(n,"length",{value:1+s(0,e.length-(arguments.length-1))})}return n};var f=function(){return l(r,i,arguments)};u?u(e.exports,"apply",{value:f}):e.exports.apply=f},4184:(e,n)=>{var t; +/*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/!function(){"use strict";var r={}.hasOwnProperty;function o(){for(var e=[],n=0;n{"use strict";e.exports=function(e,n){var t=this,r=t.constructor;return t.options=Object.assign({storeInstancesGlobally:!0},n||{}),t.callbacks={},t.directMap={},t.sequenceLevels={},t.resetTimer=null,t.ignoreNextKeyup=!1,t.ignoreNextKeypress=!1,t.nextExpectedAction=!1,t.element=e,t.addEvents(),t.options.storeInstancesGlobally&&r.instances.push(t),t},e.exports.prototype.bind=t(2207),e.exports.prototype.bindMultiple=t(3396),e.exports.prototype.unbind=t(9208),e.exports.prototype.trigger=t(9855),e.exports.prototype.reset=t(6214),e.exports.prototype.stopCallback=t(3450),e.exports.prototype.handleKey=t(3067),e.exports.prototype.addEvents=t(718),e.exports.prototype.bindSingle=t(8763),e.exports.prototype.getKeyInfo=t(5825),e.exports.prototype.pickBestAction=t(8608),e.exports.prototype.getReverseMap=t(3956),e.exports.prototype.getMatches=t(3373),e.exports.prototype.resetSequences=t(3346),e.exports.prototype.fireCallback=t(2684),e.exports.prototype.bindSequence=t(7103),e.exports.prototype.resetSequenceTimer=t(7309),e.exports.prototype.detach=t(7554),e.exports.instances=[],e.exports.reset=t(1822),e.exports.REVERSE_MAP=null},718:(e,n,t)=>{"use strict";e.exports=function(){var e=this,n=t(4323),r=e.element;e.eventHandler=t(9646).bind(e),n(r,"keypress",e.eventHandler),n(r,"keydown",e.eventHandler),n(r,"keyup",e.eventHandler)}},2207:e=>{"use strict";e.exports=function(e,n,t){return e=e instanceof Array?e:[e],this.bindMultiple(e,n,t),this}},3396:e=>{"use strict";e.exports=function(e,n,t){for(var r=0;r{"use strict";e.exports=function(e,n,r,o){var i=this;function a(n){return function(){i.nextExpectedAction=n,++i.sequenceLevels[e],i.resetSequenceTimer()}}function l(n){var a;i.fireCallback(r,n,e),"keyup"!==o&&(a=t(6770),i.ignoreNextKeyup=a(n)),setTimeout((function(){i.resetSequences()}),10)}i.sequenceLevels[e]=0;for(var c=0;c{"use strict";e.exports=function(e,n,t,r,o){var i=this;i.directMap[e+":"+t]=n;var a,l=(e=e.replace(/\s+/g," ")).split(" ");l.length>1?i.bindSequence(e,l,n,t):(a=i.getKeyInfo(e,t),i.callbacks[a.key]=i.callbacks[a.key]||[],i.getMatches(a.key,a.modifiers,{type:a.action},r,e,o),i.callbacks[a.key][r?"unshift":"push"]({callback:n,modifiers:a.modifiers,action:a.action,seq:r,level:o,combo:e}))}},7554:(e,n,t)=>{var r=t(4323).off;e.exports=function(){var e=this,n=e.element;r(n,"keypress",e.eventHandler),r(n,"keydown",e.eventHandler),r(n,"keyup",e.eventHandler)}},4323:e=>{function n(e,n,t,r){return!e.addEventListener&&(n="on"+n),(e.addEventListener||e.attachEvent).call(e,n,t,r),t}e.exports=n,e.exports.on=n,e.exports.off=function(e,n,t,r){return!e.removeEventListener&&(n="on"+n),(e.removeEventListener||e.detachEvent).call(e,n,t,r),t}},2684:(e,n,t)=>{"use strict";e.exports=function(e,n,r,o){this.stopCallback(n,n.target||n.srcElement,r,o)||!1===e(n,r)&&(t(1350)(n),t(6103)(n))}},5825:(e,n,t)=>{"use strict";e.exports=function(e,n){var r,o,i,a,l,c,u=[];for(r=t(4520)(e),a=t(7549),l=t(5355),c=t(8581),i=0;i{"use strict";e.exports=function(e,n,r,o,i,a){var l,c,u,s,f=this,p=[],d=r.type;"keypress"!==d||r.code&&"Arrow"===r.code.slice(0,5)||(f.callbacks["any-character"]||[]).forEach((function(e){p.push(e)}));if(!f.callbacks[e])return p;for(u=t(8581),"keyup"===d&&u(e)&&(n=[e]),l=0;l{"use strict";e.exports=function(){var e,n=this.constructor;if(!n.REVERSE_MAP)for(var r in n.REVERSE_MAP={},e=t(4766))r>95&&r<112||e.hasOwnProperty(r)&&(n.REVERSE_MAP[e[r]]=r);return n.REVERSE_MAP}},3067:(e,n,t)=>{"use strict";e.exports=function(e,n,r){var o,i,a,l,c=this,u={},s=0,f=!1;for(o=c.getMatches(e,n,r),i=0;i{"use strict";e.exports=function(e){var n,r=this;"number"!=typeof e.which&&(e.which=e.keyCode);var o=t(6770)(e);void 0!==o&&("keyup"!==e.type||r.ignoreNextKeyup!==o?(n=t(4610),r.handleKey(o,n(e),e)):r.ignoreNextKeyup=!1)}},5532:e=>{"use strict";e.exports=function(e,n){return e.sort().join(",")===n.sort().join(",")}},8608:e=>{"use strict";e.exports=function(e,n,t){return t||(t=this.getReverseMap()[e]?"keydown":"keypress"),"keypress"===t&&n.length&&(t="keydown"),t}},6214:e=>{"use strict";e.exports=function(){return this.callbacks={},this.directMap={},this}},7309:e=>{"use strict";e.exports=function(){var e=this;clearTimeout(e.resetTimer),e.resetTimer=setTimeout((function(){e.resetSequences()}),1e3)}},3346:e=>{"use strict";e.exports=function(e){var n=this;e=e||{};var t,r=!1;for(t in n.sequenceLevels)e[t]?r=!0:n.sequenceLevels[t]=0;r||(n.nextExpectedAction=!1)}},3450:e=>{"use strict";e.exports=function(e,n){if((" "+n.className+" ").indexOf(" combokeys ")>-1)return!1;var t=n.tagName.toLowerCase();return"input"===t||"select"===t||"textarea"===t||n.isContentEditable}},9855:e=>{"use strict";e.exports=function(e,n){return this.directMap[e+":"+n]&&this.directMap[e+":"+n]({},e),this}},9208:e=>{"use strict";e.exports=function(e,n){return this.bind(e,(function(){}),n)}},1822:e=>{"use strict";e.exports=function(){this.instances.forEach((function(e){e.reset()}))}},6770:(e,n,t)=>{"use strict";e.exports=function(e){var n,r;if(n=t(4766),r=t(5295),"keypress"===e.type){var o=String.fromCharCode(e.which);return e.shiftKey||(o=o.toLowerCase()),o}return void 0!==n[e.which]?n[e.which]:void 0!==r[e.which]?r[e.which]:String.fromCharCode(e.which).toLowerCase()}},4610:e=>{"use strict";e.exports=function(e){var n=[];return e.shiftKey&&n.push("shift"),e.altKey&&n.push("alt"),e.ctrlKey&&n.push("ctrl"),e.metaKey&&n.push("meta"),n}},8581:e=>{"use strict";e.exports=function(e){return"shift"===e||"ctrl"===e||"alt"===e||"meta"===e}},4520:e=>{"use strict";e.exports=function(e){return"+"===e?["+"]:e.split("+")}},1350:e=>{"use strict";e.exports=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1}},5355:e=>{"use strict";e.exports={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"}},7549:e=>{"use strict";e.exports={option:"alt",command:"meta",return:"enter",escape:"esc",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"}},5295:e=>{"use strict";e.exports={106:"*",107:"plus",109:"minus",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"}},4766:e=>{"use strict";e.exports={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",173:"minus",187:"plus",189:"minus",224:"meta"};for(var n=1;n<20;++n)e.exports[111+n]="f"+n;for(n=0;n<=9;++n)e.exports[n+96]=n},6103:e=>{"use strict";e.exports=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}},3362:()=>{var e;!function(){var e=Math.PI,n=2*e,t=e/180,r=document.createElement("div");document.head.appendChild(r);var o=self.ConicGradient=function(e){o.all.push(this),e=e||{},this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.repeating=!!e.repeating,this.size=e.size||Math.max(innerWidth,innerHeight),this.canvas.width=this.canvas.height=this.size;var n=e.stops;this.stops=(n||"").split(/\s*,(?![^(]*\))\s*/),this.from=0;for(var t=0;t0){var i=this.stops[0].clone();i.pos=0,this.stops.unshift(i)}if(void 0===this.stops[this.stops.length-1].pos)this.stops[this.stops.length-1].pos=1;else if(!this.repeating&&this.stops[this.stops.length-1].pos<1){var a=this.stops[this.stops.length-1].clone();a.pos=1,this.stops.push(a)}if(this.stops.forEach((function(e,n){if(void 0===e.pos){for(var t=n+1;this[t];t++)if(void 0!==this[t].pos){e.pos=this[n-1].pos+(this[t].pos-this[n-1].pos)/(t-n+1);break}}else n>0&&(e.pos=Math.max(e.pos,this[n-1].pos))}),this.stops),this.repeating){var l=(n=this.stops.slice())[n.length-1].pos-n[0].pos;for(t=0;this.stops[this.stops.length-1].pos<1&&t<1e4;t++)for(var c=0;c'},get png(){return this.canvas.toDataURL()},get r(){return Math.sqrt(2)*this.size/2},paint:function(){var e,n,r,o=this.context,i=this.r,a=this.size/2,l=0,c=this.stops[l];o.translate(this.size/2,this.size/2),o.rotate(-90*t),o.rotate(this.from*t),o.translate(-this.size/2,-this.size/2);for(var u=0;u<360;){if(u/360+1e-5>=c.pos){do{e=c,l++,c=this.stops[l]}while(c&&c!=e&&c.pos===e.pos);if(!c)break;var s=e.color+""==c.color+""&&e!=c;n=e.color.map((function(e,n){return c.color[n]-e}))}r=(u/360-e.pos)/(c.pos-e.pos);var f=s?c.color:n.map((function(n,t){var o=n*r+e.color[t];return t<3?255&o:o}));if(o.fillStyle="rgba("+f.join(",")+")",o.beginPath(),o.moveTo(a,a),s)var p=360*(c.pos-e.pos);else p=.5;var d=u*t,h=(d=Math.min(360*t,d))+p*t;h=Math.min(360*t,h+.02),o.arc(a,a,i,d,h),o.closePath(),o.fill(),u+=p}}},o.ColorStop=function(e,t){if(this.gradient=e,t){var r=t.match(/^(.+?)(?:\s+([\d.]+)(%|deg|turn|grad|rad)?)?(?:\s+([\d.]+)(%|deg|turn|grad|rad)?)?\s*$/);if(this.color=o.ColorStop.colorToRGBA(r[1]),r[2]){var i=r[3];"%"==i||"0"===r[2]&&!i?this.pos=r[2]/100:"turn"==i?this.pos=+r[2]:"deg"==i?this.pos=r[2]/360:"grad"==i?this.pos=r[2]/400:"rad"==i&&(this.pos=r[2]/n)}r[4]&&(this.next=new o.ColorStop(e,r[1]+" "+r[4]+r[5]))}},o.ColorStop.prototype={clone:function(){var e=new o.ColorStop(this.gradient);return e.color=this.color,e.pos=this.pos,e},toString:function(){return"rgba("+this.color.join(", ")+") "+100*this.pos+"%"}},o.ColorStop.colorToRGBA=function(e){if(!Array.isArray(e)&&-1==e.indexOf("from")){r.style.color=e;var n=getComputedStyle(r).color.match(/rgba?\(([\d.]+), ([\d.]+), ([\d.]+)(?:, ([\d.]+))?\)/);return n&&(n.shift(),(n=n.map((function(e){return+e})))[3]=isNaN(n[3])?1:n[3]),n||[0,0,0,0]}return e}}(),self.StyleFix&&((e=document.createElement("p")).style.backgroundImage="conic-gradient(white, black)",e.style.backgroundImage=PrefixFree.prefix+"conic-gradient(white, black)",e.style.backgroundImage||StyleFix.register((function(e,n){return e.indexOf("conic-gradient")>-1&&(e=e.replace(/(?:repeating-)?conic-gradient\(\s*((?:\([^()]+\)|[^;()}])+?)\)/g,(function(e,n){return new ConicGradient({stops:n,repeating:e.indexOf("repeating-")>-1})}))),e})))},9662:(e,n,t)=>{var r=t(7854),o=t(614),i=t(6330),a=r.TypeError;e.exports=function(e){if(o(e))return e;throw a(i(e)+" is not a function")}},9483:(e,n,t)=>{var r=t(7854),o=t(4411),i=t(6330),a=r.TypeError;e.exports=function(e){if(o(e))return e;throw a(i(e)+" is not a constructor")}},6077:(e,n,t)=>{var r=t(7854),o=t(614),i=r.String,a=r.TypeError;e.exports=function(e){if("object"==typeof e||o(e))return e;throw a("Can't set "+i(e)+" as a prototype")}},1223:(e,n,t)=>{var r=t(5112),o=t(30),i=t(3070),a=r("unscopables"),l=Array.prototype;null==l[a]&&i.f(l,a,{configurable:!0,value:o(null)}),e.exports=function(e){l[a][e]=!0}},1530:(e,n,t)=>{"use strict";var r=t(8710).charAt;e.exports=function(e,n,t){return n+(t?r(e,n).length:1)}},5787:(e,n,t)=>{var r=t(7854),o=t(7976),i=r.TypeError;e.exports=function(e,n){if(o(n,e))return e;throw i("Incorrect invocation")}},9670:(e,n,t)=>{var r=t(7854),o=t(111),i=r.String,a=r.TypeError;e.exports=function(e){if(o(e))return e;throw a(i(e)+" is not an object")}},7556:(e,n,t)=>{var r=t(7293);e.exports=r((function(){if("function"==typeof ArrayBuffer){var e=new ArrayBuffer(8);Object.isExtensible(e)&&Object.defineProperty(e,"a",{value:8})}}))},8533:(e,n,t)=>{"use strict";var r=t(2092).forEach,o=t(9341)("forEach");e.exports=o?[].forEach:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}},8457:(e,n,t)=>{"use strict";var r=t(7854),o=t(9974),i=t(6916),a=t(7908),l=t(3411),c=t(7659),u=t(4411),s=t(6244),f=t(6135),p=t(8554),d=t(1246),h=r.Array;e.exports=function(e){var n=a(e),t=u(this),r=arguments.length,g=r>1?arguments[1]:void 0,v=void 0!==g;v&&(g=o(g,r>2?arguments[2]:void 0));var A,b,m,y,E,_,C=d(n),w=0;if(!C||this==h&&c(C))for(A=s(n),b=t?new this(A):h(A);A>w;w++)_=v?g(n[w],w):n[w],f(b,w,_);else for(E=(y=p(n,C)).next,b=t?new this:[];!(m=i(E,y)).done;w++)_=v?l(y,g,[m.value,w],!0):m.value,f(b,w,_);return b.length=w,b}},1318:(e,n,t)=>{var r=t(5656),o=t(1400),i=t(6244),a=function(e){return function(n,t,a){var l,c=r(n),u=i(c),s=o(a,u);if(e&&t!=t){for(;u>s;)if((l=c[s++])!=l)return!0}else for(;u>s;s++)if((e||s in c)&&c[s]===t)return e||s||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},2092:(e,n,t)=>{var r=t(9974),o=t(1702),i=t(8361),a=t(7908),l=t(6244),c=t(5417),u=o([].push),s=function(e){var n=1==e,t=2==e,o=3==e,s=4==e,f=6==e,p=7==e,d=5==e||f;return function(h,g,v,A){for(var b,m,y=a(h),E=i(y),_=r(g,v),C=l(E),w=0,x=A||c,k=n?x(h,C):t||p?x(h,0):void 0;C>w;w++)if((d||w in E)&&(m=_(b=E[w],w,y),e))if(n)k[w]=m;else if(m)switch(e){case 3:return!0;case 5:return b;case 6:return w;case 2:u(k,b)}else switch(e){case 4:return!1;case 7:u(k,b)}return f?-1:o||s?s:k}};e.exports={forEach:s(0),map:s(1),filter:s(2),some:s(3),every:s(4),find:s(5),findIndex:s(6),filterReject:s(7)}},1194:(e,n,t)=>{var r=t(7293),o=t(5112),i=t(7392),a=o("species");e.exports=function(e){return i>=51||!r((function(){var n=[];return(n.constructor={})[a]=function(){return{foo:1}},1!==n[e](Boolean).foo}))}},9341:(e,n,t)=>{"use strict";var r=t(7293);e.exports=function(e,n){var t=[][e];return!!t&&r((function(){t.call(null,n||function(){throw 1},1)}))}},3671:(e,n,t)=>{var r=t(7854),o=t(9662),i=t(7908),a=t(8361),l=t(6244),c=r.TypeError,u=function(e){return function(n,t,r,u){o(t);var s=i(n),f=a(s),p=l(s),d=e?p-1:0,h=e?-1:1;if(r<2)for(;;){if(d in f){u=f[d],d+=h;break}if(d+=h,e?d<0:p<=d)throw c("Reduce of empty array with no initial value")}for(;e?d>=0:p>d;d+=h)d in f&&(u=t(u,f[d],d,s));return u}};e.exports={left:u(!1),right:u(!0)}},206:(e,n,t)=>{var r=t(1702);e.exports=r([].slice)},4362:(e,n,t)=>{var r=t(206),o=Math.floor,i=function(e,n){var t=e.length,c=o(t/2);return t<8?a(e,n):l(e,i(r(e,0,c),n),i(r(e,c),n),n)},a=function(e,n){for(var t,r,o=e.length,i=1;i0;)e[r]=e[--r];r!==i++&&(e[r]=t)}return e},l=function(e,n,t,r){for(var o=n.length,i=t.length,a=0,l=0;a{var r=t(7854),o=t(3157),i=t(4411),a=t(111),l=t(5112)("species"),c=r.Array;e.exports=function(e){var n;return o(e)&&(n=e.constructor,(i(n)&&(n===c||o(n.prototype))||a(n)&&null===(n=n[l]))&&(n=void 0)),void 0===n?c:n}},5417:(e,n,t)=>{var r=t(7475);e.exports=function(e,n){return new(r(e))(0===n?0:n)}},3411:(e,n,t)=>{var r=t(9670),o=t(9212);e.exports=function(e,n,t,i){try{return i?n(r(t)[0],t[1]):n(t)}catch(n){o(e,"throw",n)}}},7072:(e,n,t)=>{var r=t(5112)("iterator"),o=!1;try{var i=0,a={next:function(){return{done:!!i++}},return:function(){o=!0}};a[r]=function(){return this},Array.from(a,(function(){throw 2}))}catch(e){}e.exports=function(e,n){if(!n&&!o)return!1;var t=!1;try{var i={};i[r]=function(){return{next:function(){return{done:t=!0}}}},e(i)}catch(e){}return t}},4326:(e,n,t)=>{var r=t(1702),o=r({}.toString),i=r("".slice);e.exports=function(e){return i(o(e),8,-1)}},648:(e,n,t)=>{var r=t(7854),o=t(1694),i=t(614),a=t(4326),l=t(5112)("toStringTag"),c=r.Object,u="Arguments"==a(function(){return arguments}());e.exports=o?a:function(e){var n,t,r;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(t=function(e,n){try{return e[n]}catch(e){}}(n=c(e),l))?t:u?a(n):"Object"==(r=a(n))&&i(n.callee)?"Arguments":r}},5631:(e,n,t)=>{"use strict";var r=t(3070).f,o=t(30),i=t(2248),a=t(9974),l=t(5787),c=t(408),u=t(654),s=t(6340),f=t(9781),p=t(2423).fastKey,d=t(9909),h=d.set,g=d.getterFor;e.exports={getConstructor:function(e,n,t,u){var s=e((function(e,r){l(e,d),h(e,{type:n,index:o(null),first:void 0,last:void 0,size:0}),f||(e.size=0),null!=r&&c(r,e[u],{that:e,AS_ENTRIES:t})})),d=s.prototype,v=g(n),A=function(e,n,t){var r,o,i=v(e),a=b(e,n);return a?a.value=t:(i.last=a={index:o=p(n,!0),key:n,value:t,previous:r=i.last,next:void 0,removed:!1},i.first||(i.first=a),r&&(r.next=a),f?i.size++:e.size++,"F"!==o&&(i.index[o]=a)),e},b=function(e,n){var t,r=v(e),o=p(n);if("F"!==o)return r.index[o];for(t=r.first;t;t=t.next)if(t.key==n)return t};return i(d,{clear:function(){for(var e=v(this),n=e.index,t=e.first;t;)t.removed=!0,t.previous&&(t.previous=t.previous.next=void 0),delete n[t.index],t=t.next;e.first=e.last=void 0,f?e.size=0:this.size=0},delete:function(e){var n=this,t=v(n),r=b(n,e);if(r){var o=r.next,i=r.previous;delete t.index[r.index],r.removed=!0,i&&(i.next=o),o&&(o.previous=i),t.first==r&&(t.first=o),t.last==r&&(t.last=i),f?t.size--:n.size--}return!!r},forEach:function(e){for(var n,t=v(this),r=a(e,arguments.length>1?arguments[1]:void 0);n=n?n.next:t.first;)for(r(n.value,n.key,this);n&&n.removed;)n=n.previous},has:function(e){return!!b(this,e)}}),i(d,t?{get:function(e){var n=b(this,e);return n&&n.value},set:function(e,n){return A(this,0===e?0:e,n)}}:{add:function(e){return A(this,e=0===e?0:e,e)}}),f&&r(d,"size",{get:function(){return v(this).size}}),s},setStrong:function(e,n,t){var r=n+" Iterator",o=g(n),i=g(r);u(e,n,(function(e,n){h(this,{type:r,target:e,state:o(e),kind:n,last:void 0})}),(function(){for(var e=i(this),n=e.kind,t=e.last;t&&t.removed;)t=t.previous;return e.target&&(e.last=t=t?t.next:e.state.first)?"keys"==n?{value:t.key,done:!1}:"values"==n?{value:t.value,done:!1}:{value:[t.key,t.value],done:!1}:(e.target=void 0,{value:void 0,done:!0})}),t?"entries":"values",!t,!0),s(n)}}},9320:(e,n,t)=>{"use strict";var r=t(1702),o=t(2248),i=t(2423).getWeakData,a=t(9670),l=t(111),c=t(5787),u=t(408),s=t(2092),f=t(2597),p=t(9909),d=p.set,h=p.getterFor,g=s.find,v=s.findIndex,A=r([].splice),b=0,m=function(e){return e.frozen||(e.frozen=new y)},y=function(){this.entries=[]},E=function(e,n){return g(e.entries,(function(e){return e[0]===n}))};y.prototype={get:function(e){var n=E(this,e);if(n)return n[1]},has:function(e){return!!E(this,e)},set:function(e,n){var t=E(this,e);t?t[1]=n:this.entries.push([e,n])},delete:function(e){var n=v(this.entries,(function(n){return n[0]===e}));return~n&&A(this.entries,n,1),!!~n}},e.exports={getConstructor:function(e,n,t,r){var s=e((function(e,o){c(e,p),d(e,{type:n,id:b++,frozen:void 0}),null!=o&&u(o,e[r],{that:e,AS_ENTRIES:t})})),p=s.prototype,g=h(n),v=function(e,n,t){var r=g(e),o=i(a(n),!0);return!0===o?m(r).set(n,t):o[r.id]=t,e};return o(p,{delete:function(e){var n=g(this);if(!l(e))return!1;var t=i(e);return!0===t?m(n).delete(e):t&&f(t,n.id)&&delete t[n.id]},has:function(e){var n=g(this);if(!l(e))return!1;var t=i(e);return!0===t?m(n).has(e):t&&f(t,n.id)}}),o(p,t?{get:function(e){var n=g(this);if(l(e)){var t=i(e);return!0===t?m(n).get(e):t?t[n.id]:void 0}},set:function(e,n){return v(this,e,n)}}:{add:function(e){return v(this,e,!0)}}),s}}},7710:(e,n,t)=>{"use strict";var r=t(2109),o=t(7854),i=t(1702),a=t(4705),l=t(1320),c=t(2423),u=t(408),s=t(5787),f=t(614),p=t(111),d=t(7293),h=t(7072),g=t(8003),v=t(9587);e.exports=function(e,n,t){var A=-1!==e.indexOf("Map"),b=-1!==e.indexOf("Weak"),m=A?"set":"add",y=o[e],E=y&&y.prototype,_=y,C={},w=function(e){var n=i(E[e]);l(E,e,"add"==e?function(e){return n(this,0===e?0:e),this}:"delete"==e?function(e){return!(b&&!p(e))&&n(this,0===e?0:e)}:"get"==e?function(e){return b&&!p(e)?void 0:n(this,0===e?0:e)}:"has"==e?function(e){return!(b&&!p(e))&&n(this,0===e?0:e)}:function(e,t){return n(this,0===e?0:e,t),this})};if(a(e,!f(y)||!(b||E.forEach&&!d((function(){(new y).entries().next()})))))_=t.getConstructor(n,e,A,m),c.enable();else if(a(e,!0)){var x=new _,k=x[m](b?{}:-0,1)!=x,S=d((function(){x.has(1)})),O=h((function(e){new y(e)})),B=!b&&d((function(){for(var e=new y,n=5;n--;)e[m](n,n);return!e.has(-0)}));O||((_=n((function(e,n){s(e,E);var t=v(new y,e,_);return null!=n&&u(n,t[m],{that:t,AS_ENTRIES:A}),t}))).prototype=E,E.constructor=_),(S||B)&&(w("delete"),w("has"),A&&w("get")),(B||k)&&w(m),b&&E.clear&&delete E.clear}return C[e]=_,r({global:!0,forced:_!=y},C),g(_,e),b||t.setStrong(_,e,A),_}},9920:(e,n,t)=>{var r=t(2597),o=t(3887),i=t(1236),a=t(3070);e.exports=function(e,n){for(var t=o(n),l=a.f,c=i.f,u=0;u{var r=t(5112)("match");e.exports=function(e){var n=/./;try{"/./"[e](n)}catch(t){try{return n[r]=!1,"/./"[e](n)}catch(e){}}return!1}},8544:(e,n,t)=>{var r=t(7293);e.exports=!r((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},4230:(e,n,t)=>{var r=t(1702),o=t(4488),i=t(1340),a=/"/g,l=r("".replace);e.exports=function(e,n,t,r){var c=i(o(e)),u="<"+n;return""!==t&&(u+=" "+t+'="'+l(i(r),a,""")+'"'),u+">"+c+""}},4994:(e,n,t)=>{"use strict";var r=t(3383).IteratorPrototype,o=t(30),i=t(9114),a=t(8003),l=t(7497),c=function(){return this};e.exports=function(e,n,t){var u=n+" Iterator";return e.prototype=o(r,{next:i(1,t)}),a(e,u,!1,!0),l[u]=c,e}},8880:(e,n,t)=>{var r=t(9781),o=t(3070),i=t(9114);e.exports=r?function(e,n,t){return o.f(e,n,i(1,t))}:function(e,n,t){return e[n]=t,e}},9114:e=>{e.exports=function(e,n){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:n}}},6135:(e,n,t)=>{"use strict";var r=t(4948),o=t(3070),i=t(9114);e.exports=function(e,n,t){var a=r(n);a in e?o.f(e,a,i(0,t)):e[a]=t}},8709:(e,n,t)=>{"use strict";var r=t(7854),o=t(9670),i=t(2140),a=r.TypeError;e.exports=function(e){if(o(this),"string"===e||"default"===e)e="string";else if("number"!==e)throw a("Incorrect hint");return i(this,e)}},654:(e,n,t)=>{"use strict";var r=t(2109),o=t(6916),i=t(1913),a=t(6530),l=t(614),c=t(4994),u=t(9518),s=t(7674),f=t(8003),p=t(8880),d=t(1320),h=t(5112),g=t(7497),v=t(3383),A=a.PROPER,b=a.CONFIGURABLE,m=v.IteratorPrototype,y=v.BUGGY_SAFARI_ITERATORS,E=h("iterator"),_="keys",C="values",w="entries",x=function(){return this};e.exports=function(e,n,t,a,h,v,k){c(t,n,a);var S,O,B,I=function(e){if(e===h&&R)return R;if(!y&&e in j)return j[e];switch(e){case _:case C:case w:return function(){return new t(this,e)}}return function(){return new t(this)}},T=n+" Iterator",P=!1,j=e.prototype,z=j[E]||j["@@iterator"]||h&&j[h],R=!y&&z||I(h),M="Array"==n&&j.entries||z;if(M&&(S=u(M.call(new e)))!==Object.prototype&&S.next&&(i||u(S)===m||(s?s(S,m):l(S[E])||d(S,E,x)),f(S,T,!0,!0),i&&(g[T]=x)),A&&h==C&&z&&z.name!==C&&(!i&&b?p(j,"name",C):(P=!0,R=function(){return o(z,this)})),h)if(O={values:I(C),keys:v?R:I(_),entries:I(w)},k)for(B in O)(y||P||!(B in j))&&d(j,B,O[B]);else r({target:n,proto:!0,forced:y||P},O);return i&&!k||j[E]===R||d(j,E,R,{name:h}),g[n]=R,O}},7235:(e,n,t)=>{var r=t(857),o=t(2597),i=t(6061),a=t(3070).f;e.exports=function(e){var n=r.Symbol||(r.Symbol={});o(n,e)||a(n,e,{value:i.f(e)})}},9781:(e,n,t)=>{var r=t(7293);e.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},317:(e,n,t)=>{var r=t(7854),o=t(111),i=r.document,a=o(i)&&o(i.createElement);e.exports=function(e){return a?i.createElement(e):{}}},8324:e=>{e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},8509:(e,n,t)=>{var r=t(317)("span").classList,o=r&&r.constructor&&r.constructor.prototype;e.exports=o===Object.prototype?void 0:o},8886:(e,n,t)=>{var r=t(8113).match(/firefox\/(\d+)/i);e.exports=!!r&&+r[1]},256:(e,n,t)=>{var r=t(8113);e.exports=/MSIE|Trident/.test(r)},5268:(e,n,t)=>{var r=t(4326),o=t(7854);e.exports="process"==r(o.process)},8113:(e,n,t)=>{var r=t(5005);e.exports=r("navigator","userAgent")||""},7392:(e,n,t)=>{var r,o,i=t(7854),a=t(8113),l=i.process,c=i.Deno,u=l&&l.versions||c&&c.version,s=u&&u.v8;s&&(o=(r=s.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&a&&(!(r=a.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/))&&(o=+r[1]),e.exports=o},8008:(e,n,t)=>{var r=t(8113).match(/AppleWebKit\/(\d+)\./);e.exports=!!r&&+r[1]},748:e=>{e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},2109:(e,n,t)=>{var r=t(7854),o=t(1236).f,i=t(8880),a=t(1320),l=t(3505),c=t(9920),u=t(4705);e.exports=function(e,n){var t,s,f,p,d,h=e.target,g=e.global,v=e.stat;if(t=g?r:v?r[h]||l(h,{}):(r[h]||{}).prototype)for(s in n){if(p=n[s],f=e.noTargetGet?(d=o(t,s))&&d.value:t[s],!u(g?s:h+(v?".":"#")+s,e.forced)&&void 0!==f){if(typeof p==typeof f)continue;c(p,f)}(e.sham||f&&f.sham)&&i(p,"sham",!0),a(t,s,p,e)}}},7293:e=>{e.exports=function(e){try{return!!e()}catch(e){return!0}}},7007:(e,n,t)=>{"use strict";t(4916);var r=t(1702),o=t(1320),i=t(2261),a=t(7293),l=t(5112),c=t(8880),u=l("species"),s=RegExp.prototype;e.exports=function(e,n,t,f){var p=l(e),d=!a((function(){var n={};return n[p]=function(){return 7},7!=""[e](n)})),h=d&&!a((function(){var n=!1,t=/a/;return"split"===e&&((t={}).constructor={},t.constructor[u]=function(){return t},t.flags="",t[p]=/./[p]),t.exec=function(){return n=!0,null},t[p](""),!n}));if(!d||!h||t){var g=r(/./[p]),v=n(p,""[e],(function(e,n,t,o,a){var l=r(e),c=n.exec;return c===i||c===s.exec?d&&!a?{done:!0,value:g(n,t,o)}:{done:!0,value:l(t,n,o)}:{done:!1}}));o(String.prototype,e,v[0]),o(s,p,v[1])}f&&c(s[p],"sham",!0)}},6677:(e,n,t)=>{var r=t(7293);e.exports=!r((function(){return Object.isExtensible(Object.preventExtensions({}))}))},2104:e=>{var n=Function.prototype,t=n.apply,r=n.bind,o=n.call;e.exports="object"==typeof Reflect&&Reflect.apply||(r?o.bind(t):function(){return o.apply(t,arguments)})},9974:(e,n,t)=>{var r=t(1702),o=t(9662),i=r(r.bind);e.exports=function(e,n){return o(e),void 0===n?e:i?i(e,n):function(){return e.apply(n,arguments)}}},7065:(e,n,t)=>{"use strict";var r=t(7854),o=t(1702),i=t(9662),a=t(111),l=t(2597),c=t(206),u=r.Function,s=o([].concat),f=o([].join),p={},d=function(e,n,t){if(!l(p,n)){for(var r=[],o=0;o{var n=Function.prototype.call;e.exports=n.bind?n.bind(n):function(){return n.apply(n,arguments)}},6530:(e,n,t)=>{var r=t(9781),o=t(2597),i=Function.prototype,a=r&&Object.getOwnPropertyDescriptor,l=o(i,"name"),c=l&&"something"===function(){}.name,u=l&&(!r||r&&a(i,"name").configurable);e.exports={EXISTS:l,PROPER:c,CONFIGURABLE:u}},1702:e=>{var n=Function.prototype,t=n.bind,r=n.call,o=t&&t.bind(r);e.exports=t?function(e){return e&&o(r,e)}:function(e){return e&&function(){return r.apply(e,arguments)}}},5005:(e,n,t)=>{var r=t(7854),o=t(614),i=function(e){return o(e)?e:void 0};e.exports=function(e,n){return arguments.length<2?i(r[e]):r[e]&&r[e][n]}},1246:(e,n,t)=>{var r=t(648),o=t(8173),i=t(7497),a=t(5112)("iterator");e.exports=function(e){if(null!=e)return o(e,a)||o(e,"@@iterator")||i[r(e)]}},8554:(e,n,t)=>{var r=t(7854),o=t(6916),i=t(9662),a=t(9670),l=t(6330),c=t(1246),u=r.TypeError;e.exports=function(e,n){var t=arguments.length<2?c(e):n;if(i(t))return a(o(t,e));throw u(l(e)+" is not iterable")}},8173:(e,n,t)=>{var r=t(9662);e.exports=function(e,n){var t=e[n];return null==t?void 0:r(t)}},647:(e,n,t)=>{var r=t(1702),o=t(7908),i=Math.floor,a=r("".charAt),l=r("".replace),c=r("".slice),u=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,s=/\$([$&'`]|\d{1,2})/g;e.exports=function(e,n,t,r,f,p){var d=t+e.length,h=r.length,g=s;return void 0!==f&&(f=o(f),g=u),l(p,g,(function(o,l){var u;switch(a(l,0)){case"$":return"$";case"&":return e;case"`":return c(n,0,t);case"'":return c(n,d);case"<":u=f[c(l,1,-1)];break;default:var s=+l;if(0===s)return o;if(s>h){var p=i(s/10);return 0===p?o:p<=h?void 0===r[p-1]?a(l,1):r[p-1]+a(l,1):o}u=r[s-1]}return void 0===u?"":u}))}},7854:(e,n,t)=>{var r=function(e){return e&&e.Math==Math&&e};e.exports=r("object"==typeof globalThis&&globalThis)||r("object"==typeof window&&window)||r("object"==typeof self&&self)||r("object"==typeof t.g&&t.g)||function(){return this}()||Function("return this")()},2597:(e,n,t)=>{var r=t(1702),o=t(7908),i=r({}.hasOwnProperty);e.exports=Object.hasOwn||function(e,n){return i(o(e),n)}},3501:e=>{e.exports={}},490:(e,n,t)=>{var r=t(5005);e.exports=r("document","documentElement")},4664:(e,n,t)=>{var r=t(9781),o=t(7293),i=t(317);e.exports=!r&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},8361:(e,n,t)=>{var r=t(7854),o=t(1702),i=t(7293),a=t(4326),l=r.Object,c=o("".split);e.exports=i((function(){return!l("z").propertyIsEnumerable(0)}))?function(e){return"String"==a(e)?c(e,""):l(e)}:l},9587:(e,n,t)=>{var r=t(614),o=t(111),i=t(7674);e.exports=function(e,n,t){var a,l;return i&&r(a=n.constructor)&&a!==t&&o(l=a.prototype)&&l!==t.prototype&&i(e,l),e}},2788:(e,n,t)=>{var r=t(1702),o=t(614),i=t(5465),a=r(Function.toString);o(i.inspectSource)||(i.inspectSource=function(e){return a(e)}),e.exports=i.inspectSource},2423:(e,n,t)=>{var r=t(2109),o=t(1702),i=t(3501),a=t(111),l=t(2597),c=t(3070).f,u=t(8006),s=t(1156),f=t(2050),p=t(9711),d=t(6677),h=!1,g=p("meta"),v=0,A=function(e){c(e,g,{value:{objectID:"O"+v++,weakData:{}}})},b=e.exports={enable:function(){b.enable=function(){},h=!0;var e=u.f,n=o([].splice),t={};t[g]=1,e(t).length&&(u.f=function(t){for(var r=e(t),o=0,i=r.length;o{var r,o,i,a=t(8536),l=t(7854),c=t(1702),u=t(111),s=t(8880),f=t(2597),p=t(5465),d=t(6200),h=t(3501),g="Object already initialized",v=l.TypeError,A=l.WeakMap;if(a||p.state){var b=p.state||(p.state=new A),m=c(b.get),y=c(b.has),E=c(b.set);r=function(e,n){if(y(b,e))throw new v(g);return n.facade=e,E(b,e,n),n},o=function(e){return m(b,e)||{}},i=function(e){return y(b,e)}}else{var _=d("state");h[_]=!0,r=function(e,n){if(f(e,_))throw new v(g);return n.facade=e,s(e,_,n),n},o=function(e){return f(e,_)?e[_]:{}},i=function(e){return f(e,_)}}e.exports={set:r,get:o,has:i,enforce:function(e){return i(e)?o(e):r(e,{})},getterFor:function(e){return function(n){var t;if(!u(n)||(t=o(n)).type!==e)throw v("Incompatible receiver, "+e+" required");return t}}}},7659:(e,n,t)=>{var r=t(5112),o=t(7497),i=r("iterator"),a=Array.prototype;e.exports=function(e){return void 0!==e&&(o.Array===e||a[i]===e)}},3157:(e,n,t)=>{var r=t(4326);e.exports=Array.isArray||function(e){return"Array"==r(e)}},614:e=>{e.exports=function(e){return"function"==typeof e}},4411:(e,n,t)=>{var r=t(1702),o=t(7293),i=t(614),a=t(648),l=t(5005),c=t(2788),u=function(){},s=[],f=l("Reflect","construct"),p=/^\s*(?:class|function)\b/,d=r(p.exec),h=!p.exec(u),g=function(e){if(!i(e))return!1;try{return f(u,s,e),!0}catch(e){return!1}};e.exports=!f||o((function(){var e;return g(g.call)||!g(Object)||!g((function(){e=!0}))||e}))?function(e){if(!i(e))return!1;switch(a(e)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}return h||!!d(p,c(e))}:g},4705:(e,n,t)=>{var r=t(7293),o=t(614),i=/#|\.prototype\./,a=function(e,n){var t=c[l(e)];return t==s||t!=u&&(o(n)?r(n):!!n)},l=a.normalize=function(e){return String(e).replace(i,".").toLowerCase()},c=a.data={},u=a.NATIVE="N",s=a.POLYFILL="P";e.exports=a},111:(e,n,t)=>{var r=t(614);e.exports=function(e){return"object"==typeof e?null!==e:r(e)}},1913:e=>{e.exports=!1},7850:(e,n,t)=>{var r=t(111),o=t(4326),i=t(5112)("match");e.exports=function(e){var n;return r(e)&&(void 0!==(n=e[i])?!!n:"RegExp"==o(e))}},2190:(e,n,t)=>{var r=t(7854),o=t(5005),i=t(614),a=t(7976),l=t(3307),c=r.Object;e.exports=l?function(e){return"symbol"==typeof e}:function(e){var n=o("Symbol");return i(n)&&a(n.prototype,c(e))}},408:(e,n,t)=>{var r=t(7854),o=t(9974),i=t(6916),a=t(9670),l=t(6330),c=t(7659),u=t(6244),s=t(7976),f=t(8554),p=t(1246),d=t(9212),h=r.TypeError,g=function(e,n){this.stopped=e,this.result=n},v=g.prototype;e.exports=function(e,n,t){var r,A,b,m,y,E,_,C=t&&t.that,w=!(!t||!t.AS_ENTRIES),x=!(!t||!t.IS_ITERATOR),k=!(!t||!t.INTERRUPTED),S=o(n,C),O=function(e){return r&&d(r,"normal",e),new g(!0,e)},B=function(e){return w?(a(e),k?S(e[0],e[1],O):S(e[0],e[1])):k?S(e,O):S(e)};if(x)r=e;else{if(!(A=p(e)))throw h(l(e)+" is not iterable");if(c(A)){for(b=0,m=u(e);m>b;b++)if((y=B(e[b]))&&s(v,y))return y;return new g(!1)}r=f(e,A)}for(E=r.next;!(_=i(E,r)).done;){try{y=B(_.value)}catch(e){d(r,"throw",e)}if("object"==typeof y&&y&&s(v,y))return y}return new g(!1)}},9212:(e,n,t)=>{var r=t(6916),o=t(9670),i=t(8173);e.exports=function(e,n,t){var a,l;o(e);try{if(!(a=i(e,"return"))){if("throw"===n)throw t;return t}a=r(a,e)}catch(e){l=!0,a=e}if("throw"===n)throw t;if(l)throw a;return o(a),t}},3383:(e,n,t)=>{"use strict";var r,o,i,a=t(7293),l=t(614),c=t(30),u=t(9518),s=t(1320),f=t(5112),p=t(1913),d=f("iterator"),h=!1;[].keys&&("next"in(i=[].keys())?(o=u(u(i)))!==Object.prototype&&(r=o):h=!0),null==r||a((function(){var e={};return r[d].call(e)!==e}))?r={}:p&&(r=c(r)),l(r[d])||s(r,d,(function(){return this})),e.exports={IteratorPrototype:r,BUGGY_SAFARI_ITERATORS:h}},7497:e=>{e.exports={}},6244:(e,n,t)=>{var r=t(7466);e.exports=function(e){return r(e.length)}},133:(e,n,t)=>{var r=t(7392),o=t(7293);e.exports=!!Object.getOwnPropertySymbols&&!o((function(){var e=Symbol();return!String(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},8536:(e,n,t)=>{var r=t(7854),o=t(614),i=t(2788),a=r.WeakMap;e.exports=o(a)&&/native code/.test(i(a))},3929:(e,n,t)=>{var r=t(7854),o=t(7850),i=r.TypeError;e.exports=function(e){if(o(e))throw i("The method doesn't accept regular expressions");return e}},1574:(e,n,t)=>{"use strict";var r=t(9781),o=t(1702),i=t(6916),a=t(7293),l=t(1956),c=t(5181),u=t(5296),s=t(7908),f=t(8361),p=Object.assign,d=Object.defineProperty,h=o([].concat);e.exports=!p||a((function(){if(r&&1!==p({b:1},p(d({},"a",{enumerable:!0,get:function(){d(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},n={},t=Symbol(),o="abcdefghijklmnopqrst";return e[t]=7,o.split("").forEach((function(e){n[e]=e})),7!=p({},e)[t]||l(p({},n)).join("")!=o}))?function(e,n){for(var t=s(e),o=arguments.length,a=1,p=c.f,d=u.f;o>a;)for(var g,v=f(arguments[a++]),A=p?h(l(v),p(v)):l(v),b=A.length,m=0;b>m;)g=A[m++],r&&!i(d,v,g)||(t[g]=v[g]);return t}:p},30:(e,n,t)=>{var r,o=t(9670),i=t(6048),a=t(748),l=t(3501),c=t(490),u=t(317),s=t(6200),f=s("IE_PROTO"),p=function(){},d=function(e){return" + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Changelog

+

All notable changes to this project will be documented in this document.

+

The format is based on Keep a Changelog, +and this project adheres to Semantic Versioning.

+

Unreleased

+

Added

+
    +
  • Gradle tasks are now cacheable.
  • +
  • Support for typesafe project accessors when declaring dependencies.
  • +
  • Shorthand for creating binary flags. +
    laboratory {
    +  // Generates 'Feature' with two options - 'Enabled and 'Disabled'. 'Enabled' is the default one.
    +  enabledFeature("Feature")
    +  // Generates 'Feature' with two options - 'Enabled and 'Disabled'. 'Disabled' is the default one.
    +  disabledFeature("Feature")
    +}
    +
  • +
  • Dependencies can now selectively contribute to generation process. +
    laboratory {
    +  featureFactory()
    +  featureSourceFactory()
    +  sourcedStorage()
    +  optionFactory()
    +
    +  dependency(project(":feature"), [
    +    DependencyContribution.FeatureFactory,
    +    DependencyContribution.FeatureSourceFactory, 
    +    DependencyContribution.OptionFactory, 
    +    DependencyContribution.SourcedStorage,
    +  ])
    +}
    +
  • +
+

Changed

+
    +
  • Gradle tasks are now always registered when plugin is applied in a project. If there is nothing to generate tasks will clear their respective output directories.
  • +
  • Upgrade to Kotlin 1.9.24.
  • +
  • Upgrade to Coroutines 1.8.1.
  • +
  • Upgrade to Gradle 8.7.
  • +
  • Upgrade to AGP to 8.4.1.
  • +
  • Upgrade to Wire 4.9.9.
  • +
  • Upgrade to KotlinPoet 1.16.0.
  • +
  • Upgrade to DataStore 1.1.1.
  • +
  • Upgrade to ViewPager2 1.3.2.
  • +
  • Upgrade to ViewModel-ktx 2.8.0.
  • +
  • Upgrade to Fragment-ktx 1.7.1.
  • +
  • Upgrade to RecyclerView 1.3.2.
  • +
  • Upgrade to Material 1.12.0.
  • +
  • Upgrade to Hyperion 0.9.38.
  • +
  • Downgrade target and source compatibilities versions to Java 11.
  • +
  • Change compile and target SDK to 34.
  • +
+

Fixed

+
    +
  • Gradle tasks are now correctly marked as internal.
  • +
+

1.1.0 - 2023-06-13

+

Changed

+
    +
  • Upgrade to Kotlin 1.8.21.
  • +
  • Upgrade to Coroutines 1.6.4.
  • +
  • Upgrade to Gradle 8.1.1.
  • +
  • Upgrade to Wire 4.7.0.
  • +
  • Upgrade to KotlinPoet 1.14.2.
  • +
  • Upgrade to Hyperion 0.9.37.
  • +
  • Upgrade to AppCompat 1.6.1.
  • +
  • Upgrade to ViewModel-ktx 2.6.1.
  • +
  • Upgrade to Fragment-ktx 1.5.7.
  • +
  • Upgrade to RecyclerView 1.3.0.
  • +
  • Upgrade to Material 1.9.0.
  • +
  • Upgrade target and source compatibilities versions to Java 17.
  • +
  • Change compile and target SDK to 33.
  • +
+

1.0.3 - 2022-10-01

+

Fixed

+
    +
  • Generating feature flags and related classes to empty Kotlin source sets in Kotlin 1.7.20.
  • +
+

1.0.2 - 2022-09-29

+

Fixed

+
    +
  • Fixed IllegalArgumentException: Did not find Kotlin source set after upgrading to Kotlin 1.7.20.
  • +
+

1.0.1 - 2022-06-21

+

Added

+ +

Removed

+
    +
  • CoreKtx dependency.
  • +
+

1.0.0 - 2021-02-06

+

Added

+
    +
  • setOptions(options) overload which accepts collection instead of varargs.
  • +
+

Removed

+
    +
  • ConstraintLayout dependency.
  • +
  • DynamicAnimation dependency.
  • +
+

1.0.0-rc2 - 2021-12-28

+

Changed

+
    +
  • SharedPreferencesFeatureStorage no marked as experimental due to coroutines.
  • +
  • Upgrade to Kotlin 1.6.10.
  • +
  • Upgrade to Coroutines 1.6.0.
  • +
  • Upgrade to Wire 4.0.1.
  • +
+

Fixed

+
    +
  • Handle usage of deprecated features in a generated OptionFactory.
  • +
+

Removed

+
    +
  • Builders for generator models. Models are now created via constructors and throw if data is invalid.
  • +
  • GenerationFailure interface.
  • +
  • Arrow dependency.
  • +
+

1.0.0-rc1 - 2021-12-22

+

Added

+
    +
  • Multi-module setup no longer includes other modules implicitly. Instead each module needs to be included via dependency function in Gradle. +
    laboratory {
    +  featureFactory()
    +
    +  // Before, these were included implicitly.
    +  dependency(project(":module-a"))
    +  dependency(project(":module-b"))
    +}
    +
  • +
+

Changed

+
    +
  • Upgrade Android target and compile SDK to 31.
  • +
  • Upgrade to LifecycleViewmodelKtx 2.4.0.
  • +
  • Upgrade to KotlinPoet 1.10.2.
  • +
  • Upgrade to Wire 4.0.0.
  • +
  • Upgrade to Kotlin 1.6.0.
  • +
  • Upgrade to ConstraintLayout 2.1.2.
  • +
  • Upgrade to FragmentKtx 1.4.0.
  • +
  • Upgrade to AppCompat 1.4.0.
  • +
+

Removed

+
    +
  • Groovy DSL introduced in 0.9.0 for adding feature flags.
  • +
  • projectFilter properties from Gradle plugin. Use explicit dependencies instead.
  • +
  • Deprecated API.
  • +
+

Fixed

+
    +
  • Overrides of sources in DefaultOptionFactory are now respected by Laboratory - #220.
  • +
+

0.14.0 - 2021-10-11

+

Added

+
    +
  • Better integration with remote sources, like Firebase, via OptionFactory interface. It creates feature options based on a feature key and an option name.
  • +
  • Code generation of option factory via Gradle plugin.
  • +
+

Changed

+
    +
  • Make Feature and other related classes covariant.
  • +
  • FeatureStorage functions are no longer parameterized over Feature. They accept raw class type instead.
  • +
  • Generator and Gradle plugin no longer validate package names, duplicates and other things that are checked by compiler.
  • +
  • Model builders accept now ClassName in constructor.
  • +
  • Mark SharedPreferencesFeatureStorage with ExperimentalCoroutinesApi annotation.
  • +
  • Upgrade to Kotlin 1.5.31.
  • +
  • Upgrade to Material 1.4.0.
  • +
  • Upgrade to CoreKtx 1.6.0.
  • +
  • Upgrade to DataStore 1.0.0.
  • +
  • Upgrade to AGP 4.2.2.
  • +
  • Upgrade to Hyperion 0.9.34.
  • +
  • Upgrade to FragmentKtx 1.3.6.
  • +
  • Upgrade to AppCompat 1.3.1.
  • +
  • Upgrade to ConstraintLayout 2.1.1.
  • +
  • Upgrade to ArrowKt 1.0.0.
  • +
  • Upgrade to Coroutines 1.5.2.
  • +
  • Upgrade to KotlinPoet 1.10.1.
  • +
+

Deprecated

+
    +
  • FeatureStorage.Companion.sharedPreferences(Context) function. Use overload that accepts SharedPreferences instead.
  • +
  • FeatureStorage.Companion.dataStore(() -> File) function. Use overload that accepts DataStore instead.
  • +
  • FeatureStorage.Companion.dataStore(Context, String) function. Use overload that accepts DataStore instead.
  • +
  • generate() methods on generation models. Use prepare() and operate on FileSpec directly instead.
  • +
+

Removed

+
    +
  • Dependency on Kyrie.
  • +
  • Dependency on JCenter.
  • +
+

0.13.1 - 2021-06-27

+

Changed

+
    +
  • Upgrade to Kotlin 1.5.20.
  • +
  • Upgrade to RecyclerView 1.2.1.
  • +
  • Upgrade to FragmentKtx 1.3.5.
  • +
  • Upgrade to DataStore 1.0.0-beta02.
  • +
  • Upgrade to KotlinPoet 1.9.0.
  • +
  • Upgrade to CoreKtx 1.5.0.
  • +
  • Upgrade to AppCompat 1.3.0.
  • +
+

0.13.0 - 2021-05-17

+

Changed

+
    +
  • Drop deprecated @JvmDefault and switch to JVM default modes.
  • +
  • Upgrade to Kotlin 1.5.0.
  • +
  • Upgrade to Coroutines 1.5.0.
  • +
  • Upgrade to AGP 4.2.1.
  • +
  • Upgrade to KotlinPoet 1.8.0.
  • +
  • Upgrade to RecyclerView 1.2.0.
  • +
  • Upgrade to Hyperion 0.9.32.
  • +
  • Upgrade to FragmentKtx 1.3.3.
  • +
  • Upgrade to DataStore 1.0.0-beta01.
  • +
+

0.12.1 - 2021-03-28

+

Added

+
    +
  • Indication that an option is a supervisor. If an option supervises features it has an eye icon next to it. List of supervised features is available after long pressing a chip.
  • +
  • Navigation from supervised feature to supervisor.
  • +
  • Navigation from supervisor to supervised feature.
  • +
  • Amount of offscreen feature sections in inspector can be controlled with LaboratoryActivity.Configuration.OffscreenSectionsBehavior. Default is unlimited.
  • +
+

Changed

+
    +
  • Upgrade to Kotlin 1.4.32.
  • +
  • Upgrade to LifecycleViewmodelKtx 2.3.1.
  • +
  • Upgrade to FragmentKtx 1.3.2.
  • +
  • Upgrade to Wire 3.7.0.
  • +
+

0.12.0 - 2021-03-21

+

Added

+
    +
  • Gradle plugin generates sourcedBuilder() extension function for SourcedFeatureStorage that returns custom builder with steps for each source. This makes changes to sources compile time safe.
  • +
  • Show feature’s supervisor option in inspector – #95.
  • +
+

Changed

+
    +
  • Upgrade to Coroutines 1.4.3.
  • +
  • Upgrade to AGP 4.1.3.
  • +
+

Deprecated

+
    +
  • sourcedGenerated() extension function generated by Gradle plugin.
  • +
+

0.11.0 - 2021-03-11

+

Changed

+
    +
  • Use proto3 for FeatureFlags definition.
  • +
  • Upgrade to DataStore 1.0.0-alpha08.
  • +
  • Upgrade to Kotlin 1.4.31.
  • +
  • Upgrade to Wire 3.6.1.
  • +
  • Upgrade to FragmentKtx 1.3.1.
  • +
+

0.10.0 - 2021-02-18

+

Added

+
    +
  • Parent–child relationship to Feature. This relationship is controlled with a Feature.supervisorOption property. Whenever supervisor has its option different from this value then the supervised feature flag cannot return any other option than a default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised. This relationship is recursive meaning that grandparents control grandchildren indirectly.
  • +
  • Code generation of supervisor options via Gradle plugin.
  • +
+

Changed

+
    +
  • Gradle plugin no longer changes implicit package name multiple times. Only last value that was set is applied in configuration.
  • +
  • Upgrade to DataStore 1.0.0-alpha06.
  • +
  • Upgrade to AGP 4.1.2.
  • +
  • Upgrade to Kotlin 1.4.30.
  • +
  • Upgrade to Wire 3.6.0.
  • +
  • Upgrade to Material 1.3.0.
  • +
  • Upgrade to FragmentKtx 1.3.0.
  • +
  • Upgrade to LifecycleViewmodelKtx 2.3.0.
  • +
  • Upgrade to Hyperion 0.9.31.
  • +
+

Fixed

+
    +
  • Search icon not animating on Android below SDK 24.
  • +
+

Deprecated

+
    +
  • DataStore custom builder and builder factory methods. Factory method that accepts DataStore directly should be used instead.
  • +
+

0.9.7 - 2020-12-15

+

Changed

+
    +
  • DeprecationLevel.Hidden is no longer deprecated. It was a mistake to deprecate it at all since it could work from the start.
  • +
+

0.9.6 - 2020-12-15

+

Added

+
    +
  • FeatureFactory can be now appended to another with plus operator.
  • +
  • DefaultOptionFactory can be now appended to another with plus operator.
  • +
+

Changed

+
    +
  • Use description as feature flag’s KDoc content.
  • +
  • Upgrade Kotlin to 1.4.21.
  • +
+

Deprecated

+
    +
  • Using DeprecationLevel.Hidden is temporarily treated as an error until the compiler issue is fixed.
  • +
+

Fixed

+
    +
  • Make updates to the in-memory Laboratory atomic.
  • +
+

0.9.5 - 2020-12-03

+

Added

+
    +
  • Builder pattern for LaboratoryActivity.Configuration construction.
  • +
  • Visual representation of deprecated feature flags in the QA module.
  • +
  • Visual representation of deprecated feature flags can be configured via LaboratoryActivity.Configuration builder with deprecationPhenotypeSelector() and deprecationAlignmentSelector() functions.
  • +
  • Consumer ProGuard rules to laboratory-inspector to keep @Deprecated annotation.
  • +
  • QA module displays clickable hyperlinks from a feature flag description if it contains Markdown formatted links.
  • +
+

Changed

+
    +
  • Upgrade to DataStore 1.0.0-alpha05.
  • +
+

Deprecated

+
    +
  • LaboratoryActivity.Configuration() constructor. Use LaboratoryActivity.Configuration.create() or LaboratoryActivity.Configuration.builder() instead.
  • +
+

Fixed

+
    +
  • Warning and error level deprecation on generated feature flags is now correctly suppressed.
  • +
+

0.9.4 - 2020-11-27

+

Added

+
    +
  • Kyrie 0.2.1 to laboratory-inspector.
  • +
  • DynamicAnimation 1.0.0 to laboratory-inspector.
  • +
+

Changed

+
    +
  • Animation of search feature in inspector. It no longer makes ugly visibility transitions.
  • +
  • Upgrade to Coroutines 1.4.2.
  • +
+

0.9.3 - 2020-11-23

+

Added

+
    +
  • Feature flags filtering to the QA module. Features are filtered by their name, options or source options.
  • +
  • ConstraintLayout 2.0.4 to laboratory-inspector.
  • +
+

Changed

+
    +
  • Inspector tabs are now scrollable instead of fixed.
  • +
  • Upgrade to Kotlin 1.4.20.
  • +
+

Fixed

+
    +
  • Shared preferences based FeatureStorage dispatches now changes to feature flag observers when clear() method is used. This fixes an issue with the QA module where it did not update the UI after resetting feature flags if shared preferences where used for feature flags persistence.
  • +
  • Preserve feature flags preview adapter scroll position on configuration changes.
  • +
  • External feature factories are no longer filtered out when added with the configure() function.
  • +
+

0.9.2 - 2020-11-18

+

Added

+
    +
  • BlockingLaboratory class that can read and write feature flags via blocking API.
  • +
  • blocking() function to Laboratory class that is an entry point to the blocking API.
  • +
  • Deprecation of feature flags from the Gradle plugin with deprecated(message, level) method. level argument is optional and a warning level is used by default.
  • +
+

Changed

+
    +
  • Upgrade to DataStore 1.0.0-alpha04.
  • +
+

Deprecated

+
    +
  • All blocking functions on the Laboratory class. BlockingLaboratory available via blocking() function should be used instead.
  • +
+

0.9.1 - 2020-11-12

+

Added

+
    +
  • Builder pattern for Laboratory construction.
  • +
  • DefaultOptionFactory that can substitute default options for feature flags read by Laboratory.
  • +
  • clear() function to FeatureStorage and Laboratory.
  • +
+

Changed

+
    +
  • Upgrade to DataStore 1.0.0-alpha03.
  • +
+

Deprecated

+
    +
  • Laboratory(storage) constructor. Use Laboratory.create(storage) or Laboratory.builder() instead.
  • +
+

0.9.0 - 2020-11-11

+

Added

+
    +
  • Groovy DSL for adding feature flags via Gradle plugin. This is equivalent to feature("SomeFeatureFlag") function. +
    laboratory {
    +  SomeFeatureFlag {
    +    withDefaultOption("Enabled")
    +    withOption("Disabled")
    +  }
    +}
    +
  • +
  • options extension to Class<Feature<T>> that returns all available feature flag options.
  • +
  • defaultOption extension to Class<Feature<T>> that returns a default option of a feature flag.
  • +
  • source extension to Class<Feature<*>> that returns a feature flag source if available.
  • +
  • description extension to Class<Feature<*>> that returns a feature flag description if available.
  • +
  • withOption() and withDefaultOption() to Gradle plugin for adding options to feature flags.
  • +
  • defaultOption property to Feature interface.
  • +
  • setOption() and setOptions() functions to Laboratory and FeatureStorage.
  • +
+

Changed

+
    +
  • excludeProjects plugin functions are now called projectFilter and the condition is reversed. Previously they removed projects that matched a condition. Now they allow projects that match it.
  • +
  • sourcedWith property on Feature is now named source.
  • +
  • Upgrade to Coroutines 1.4.1.
  • +
+

Deprecated

+
    +
  • withValue() and withDefaultValue() functions in Gradle plugin. withOption() and withDefaultOption() should be used instead.
  • +
  • setFeature() and setFeatures() functions. setOption() and setOptions() should be used instead.
  • +
+

Removed

+
    +
  • ProjectFilter from laboratory-gradle-plugin in favour of java.util.function.Predicate.
  • +
  • configure() overload which accepts sources factory as a separate argument.
  • +
  • isDefaultValue from Feature interface. defaultOption should be used instead.
  • +
+

Fixed

+
    +
  • Moved generateSourcedFeatureStorage task to a correct tasks group.
  • +
+

0.8.0 - 2020-10-28

+

Added

+
    +
  • KDoc documentation.
  • +
+

Changed

+
    +
  • Renamed feature/features argument in setFeature() and setFeatures() methods to value/values respectively.
  • +
  • Elevation is no longer an attribute in the IoMehowLaboratory.Theme and a regular resource is used instead. This makes sure that when an Activity theme is overridden externally it won’t crash for an unknown attribute.
  • +
  • Flatten Hyperion button to visually match other items.
  • +
  • Upgrade to Coroutines 1.4.0.
  • +
  • Upgrade to Wire 3.5.0.
  • +
+

Removed

+
    +
  • generateFactory property from sourcedFeatureStorage() method in Gradle plugin. It was added to the public API by a mistake and wasn’t responsible for anything.
  • +
  • Wire dependency from the library-shared-preferences artifact. It was added by a mistake.
  • +
  • BuildConfig classes from Android library modules.
  • +
+

0.7.0 - 2020-10-22

+

Changed

+
    +
  • Changelog format follows now Keep a Changelog format. Format is applied retroactively to this file.
  • +
  • R8 rules are now a part of META-INF of the laboratory artifact.
  • +
  • SharedPreferencesFeatureStorage is now internal.
  • +
  • Gradle plugin no longer has a runtime dependency on Android Gradle Plugin.
  • +
  • laboratory-generator generates source code compatible with the explicit API mode.
  • +
  • Set compile SDK to 30.
  • +
  • Upgrade to KotlinPoet 1.7.2.
  • +
  • Upgrade to Hyperion 0.9.30.
  • +
  • Upgrade to DataStore 1.0.0-alpha02.
  • +
+

0.6.2 - 2020-10-12

+

Added

+
    +
  • FeatureStorage extensions for creation of SharedPreferences based FeatureStorage.
  • +
  • FeatureStorage extensions for creation of DataStore based FeatureStorage.
  • +
  • Hyperion plugin can be ordered in the debug menu by overriding io_mehow_laboratory_plugin_id resource.
  • +
+

Deprecated

+
    +
  • SharedPreferenceFeatureStorage soon will become internal.
  • +
+

Changed

+
    +
  • DataStoreFeatureStorage is now internal. It is not considered a breaking change as DataStore is in the alpha stage.
  • +
+

0.6.1 - 2020-10-12

+

Fixed

+
    +
  • Hyperion plugin layout where button was on the wrong side of the debug menu.
  • +
+

0.6.0 - 2020-10-12

+

Added

+
    +
  • Feature can have now description. It can be used to add more contextual data to feature flags.
  • +
  • LaboratoryActivity observes changes to feature flags instead of loading them every time the screen is opened.
  • +
  • LaboratoryActivity displays feature flag sources next to them and allows users to select a source from a drop down menu.
  • +
  • Remote feature flag values are displayed in LaboratoryActivity if a source is not local.
  • +
  • When a remote source is used for a feature flag a value cannot be changed from LaboratoryActivity.
  • +
  • LaboratoryActivity displays feature flag descriptions if they are present.
  • +
  • LaboratoryActivity can reset feature flag values to their default state from an item in the action bar.
  • +
  • Laboratory.experimentIs() and Laboratory.experimentIsBlocking() functions that allow to check if a feature flag has particular value.
  • +
  • ViewPager2 1.0.0 dependency to laboratory-inspector.
  • +
  • RecyclerView 1.1.0 dependency to laboratory-inspector.
  • +
+

Changed

+
    +
  • LaboratoryActivity requires now a Laboratory instance for initialization. This Laboratory should share FeatureStorage with instances of Laboratory used in the application.
  • +
+

0.5.0 - 2020-10-08

+

Changed

+
    +
  • fallback nomenclature to default. This affects Gradle plugin withFallbackValue() and withFallbackSources() functions as well as isFallbackValue property on the Feature interface.
  • +
+

0.4.0 - 2020-10-08

+

Changed

+
    +
  • Name of the generated sourced FeatureStorage extension function is now sourcedGenerated() in order to align it with the generated feature factory extension function name.
  • +
+

0.3.0 - 2020-10-08

+

Added

+
    +
  • Feature flags can have multiple sources. Source is also a feature flag and is optional. If no source is available it is assumed that only a local source is controlled.
  • +
  • FeatureStorage that connects feature flags with their sources. It is available via FeatureStorage.sourced() extension function. Feature flag sources are uniquely identified only by their value names.
  • +
  • Feature flag sources can be set from the Gradle plugin with withSource("Name") and withFallbackSource("Name") functions in feature() blocks. Any source that has the name “Local” (or a variant of it) is filtered out.
  • +
  • Gradle plugin has a new sourcedStorage() function. It is responsible for generating a customized FeatureStorage that is aware of all available feature flag sources.
  • +
  • Gradle plugin has a new featureSourceFactory() function. It works similarly to featureFactory() function with a difference that it collects only feature flag sources.
  • +
  • LaboratoryActivity is now configurable with the configure() function.
  • +
  • LaboratoryActivity can display different sets of feature flags on separate tabs.
  • +
  • FragmentKtx 1.2.5 dependency to laboratory-inspector.
  • +
  • ViewModelKtx 2.2.0 dependency to laboratory-inspector.
  • +
+

Changed

+
    +
  • LaboratoryActivity.initialize() function is renamed to configure().
  • +
  • Gradle plugin factory() function is renamed to featureFactory().
  • +
+

0.2.1 - 2020-10-02

+

Added

+
    +
  • Laboratory exposes a blocking way of reading and writing feature flags. It requires an opt-in BlockingIoCall annotation.
  • +
+

Changed

+
    +
  • laboratory-android artifact is now laboratory-shared-preferences artifact.
  • +
  • laboratory-shared-preferences artifact (old laboratory-android) is no longer automatically applied by Gradle plugin in Android modules.
  • +
  • Upgrade to Kotlin 1.4.10.
  • +
  • Upgrade to CoreKtx 1.3.2.
  • +
  • Upgrade to Wire 3.4.0.
  • +
  • Upgrade to KotlinPoet 1.6.0.
  • +
+

0.2.0 - 2020-09-05

+

Added

+
    +
  • Laboratory.observe() function to observe feature flag changes via Flow.
  • +
  • Support for DataStore with the laboratory-data-store artifact.
  • +
  • Laboratory and FeatureStorage return a boolean information whether writes are successful.
  • +
  • Feature interface that is used to define feature flags.
  • +
  • Wire 3.2.2 dependency to laboratory-data-store.
  • +
+

Changed

+
    +
  • Kotlin standard library is now part of the public API.
  • +
  • Laboratory and FeatureStorage expose their API via suspend functions.
  • +
  • Gradle plugin requires exactly one feature flag value to be added with withFallbackValue("Name") function.
  • +
  • Upgrade to Kotlin 1.4.0.
  • +
  • Upgrade to Material 1.2.1.
  • +
  • Upgrade to Hyperion 0.9.29.
  • +
+

Removed

+
    +
  • @Feature annotation. Feature flags should implement the Feature interface.
  • +
+

0.1.0 - 2020-08-03

+
    +
  • Initial release.
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/css/site.css b/css/site.css new file mode 100644 index 000000000..7590b496d --- /dev/null +++ b/css/site.css @@ -0,0 +1,10 @@ +.md-typeset h1, .md-typeset h2, .md-typeset h3, .md-typeset h4 { + line-height: normal; + font-weight: bold; + color: #353535; +} + +.center { + display: block; + margin: 0 auto; +} diff --git a/gradle-plugin/index.html b/gradle-plugin/index.html new file mode 100644 index 000000000..f0032a32d --- /dev/null +++ b/gradle-plugin/index.html @@ -0,0 +1,1177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gradle plugin - Laboratory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Gradle plugin

+

Gradle plugin’s main job is to make your life easier when creating and managing feature flags. It generates features, feature factories, and customized sourced feature storage. Plugin, additionally, verifies things that cannot be represented by the API. For example, it checks if a feature flag has exactly one default option defined.

+

Under the hood, the Gradle plugin uses KotlinPoet to generate compact source files.

+
+

Info

+

The Gradle plugin automatically adds the laboratory artifact to dependencies.

+
+
+

Tip

+

The best way to understand the Gradle plugin is to check the samples. It uses most of the Gradle plugin features that most of the applications need.

+
+

Feature flags

+

Feature flags are added to the generation process with a feature() function, which uses the generateFeatureFlags Gradle task. Here is a sample configuration.

+
+

Tip

+

Check the sample with demo configuration.

+
+
apply plugin: "io.mehow.laboratory"
+
+laboratory {
+  packageName = "io.mehow.laboratory.sample"
+
+  feature("Authentication") {
+    description = "Type of authentication when opening the app"
+
+    withOption("None")
+    withOption("Fingerprint")
+    withDefaultOption("Retina")
+  }
+
+  feature("LocationTracking") {
+    packageName = "io.mehow.laboratory.location"
+
+    isPublic = false
+
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+
+    withDefaultSource("Firebase")
+    withSource("Aws")
+  }
+}
+
+

This setup creates two feature flags. Authentication and LocationTracking with options taken from the feature(name) { } block. Key things that might not be that obvious.

+
    +
  • Feature flag source visibility is inherited from a feature’s visibility.
  • +
  • If a feature flag defines a remote source, a Local source is automatically added as an option. Any custom Local sources will be filtered out.
  • +
  • If all sources are added with withSource() function, Local source will be used as a default one.
  • +
+
package io.mehow.laboratory.sample
+
+import io.mehow.laboratory.Feature
+import kotlin.Boolean
+import kotlin.String
+
+public enum class Authentication : Feature<Authentication> {
+  Password,
+  Fingerprint,
+  Retina,
+  ;
+
+  public override val defaultOption get() = Retina
+
+  public override val description: String = "Type of authentication when opening the app"
+}
+
+
package io.mehow.laboratory.location
+
+import io.mehow.laboratory.Feature
+import java.lang.Class
+import kotlin.Boolean
+import kotlin.Suppress
+
+internal enum class LocationTracking : LocationTracking<Authentication> {
+  Enabled,
+  Disabled,
+  ;
+
+  public override val defaultOption get() = Disabled
+
+  public override val source = Source::class.java
+
+  internal enum class Source : Feature<Source> {
+    Local,
+    Firebase,
+    Aws,
+    ;
+
+    public override val defaultOption get() = Firebase
+  }
+}
+
+

Supervision

+

Gradle plugin supports generation of supervised feature flags.

+
+

Tip

+

Check the sample with demo configuration.

+
+
laboratory {
+  feature("ChristmasTheme") {
+    withDefaultOption("Disabled")
+
+    withOption("Enabled") { enabledChristmas ->
+      enabledChristmas.feature("Greeting") { greeting ->
+        greeting.withDefaultOption("Hello")
+        greeting.withOption("HoHoHo")
+      }
+
+      enabledChristmas.feature("Background") { background ->
+        background.withDefaultOption("White")
+        background.withOption("Reindeer")
+        background.withOption("Snowman")
+      }
+    }
+  }
+}
+
+

This configuration generates the code below.

+
enum class ChristmasTheme : Feature<ChristmasTheme> {
+  Enabled,
+  Disabled,
+  ;
+
+  public override val defaultOption get() = Disabled
+}
+
+enum class Greeting : Feature<Greeting> {
+  Hello,
+  HoHoHo,
+  ;
+
+  public override val defaultOption get() = Hello
+
+  public override val supervisorOption get() = ChristmasTheme.Enabled
+}
+
+enum class Background : Feature<Background> {
+  White,
+  Reindeer,
+  Snowman,
+  ;
+
+  public override val defaultOption get() = White
+
+  public override val supervisorOption get() = ChristmasTheme.Enabled
+}
+
+

DSL for supervised feature flags is recursive allowing to nest them in withOption() and withDefaultOption() functions.

+

Feature flags storage

+

If your feature flags use multiple sources, you can configure the Gradle plugin to generate for you a quality of life extension function that returns a custom FeatureStorage builder.

+
apply plugin: "io.mehow.laboratory"
+
+laboratory {
+  packageName = "io.mehow.laboratory.sample"
+
+  sourcedStorage()
+
+  feature("FeatureA") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+
+    withSource("Azure")
+    withSource("Firebase")
+  }
+
+  feature("FeatureB") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+
+    withSource("Azure")
+    withSource("Aws")
+  }
+
+  feature("FeatureC") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+
+    withSource("Heroku")
+  }
+
+  feature("FeatureD") {
+    withDefaultOption("Enabled")
+    withOption("Disabled")
+  }
+}
+
+

sourcedBuilder() function uses generateSourcedFeatureStorage Gradle task that generates the code below.

+
package io.mehow.laboratory.sample
+
+import io.mehow.laboratory.FeatureStorage
+import io.mehow.laboratory.FeatureStorage.Companion.sourced
+import kotlin.String
+import kotlin.collections.Map
+import kotlin.collections.emptyMap
+import kotlin.collections.plus
+import kotlin.to
+
+internal fun FeatureStorage.Companion.sourcedBuilder(localSource: FeatureStorage): AwsStep =
+    Builder(localSource, emptyMap())
+
+internal interface AwsStep {
+  public fun awsSource(source: FeatureStorage): AzureStep
+}
+
+internal interface AzureStep {
+  public fun azureSource(source: FeatureStorage): FirebaseStep
+}
+
+internal interface FirebaseStep {
+  public fun firebaseSource(source: FeatureStorage): HerokuStep
+}
+
+internal interface HerokuStep {
+  public fun herokuSource(source: FeatureStorage): BuildingStep
+}
+
+internal interface BuildingStep {
+  public fun build(): FeatureStorage
+}
+
+private data class Builder(
+  private val localSource: FeatureStorage,
+  private val remoteSources: Map<String, FeatureStorage>
+) : AwsStep, AzureStep, FirebaseStep, HerokuStep, BuildingStep {
+  public override fun awsSourceSource(source: FeatureStorage): AzureStep = copy(
+    remoteSources = remoteSources + ("Firebase" to source)
+  )
+
+  public override fun azureSource(source: FeatureStorage): FirebaseStep = copy(
+    remoteSources = remoteSources + ("Azure" to source)
+  )
+
+  public override fun firebaseSource(source: FeatureStorage): HerokuStep = copy(
+    remoteSources = remoteSources + ("Firebase" to source)
+  )
+
+  public override fun herokuSource(source: FeatureStorage): BuildingStep = copy(
+    remoteSources = remoteSources + ("Heroku" to source)
+  )
+
+  public override fun build(): FeatureStorage = sourced(localSource, remoteSources)
+}
+
+

Feature flags factory

+

The generation of feature flags factory is useful if you use the QA module.

+
+

Tip

+

Check the samples with demo configurations.

+
+
apply plugin: "io.mehow.laboratory"
+
+laboratory {
+  packageName = "io.mehow.laboratory.sample"
+
+  featureFactory()
+
+  feature("FeatureA") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+
+  feature("FeatureB") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+
+  feature("FeatureC") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+}
+
+

featureFactory() uses generateFeatureFactory Gradle task that generates the code below. Class.forname() is used for lookup instead of the direct reference to classes because there is no guarantee that feature flags are directly available in the module that generates the factory if feature flags come, for example, as transitive dependencies of other modules.

+
package io.mehow.laboratory.sample
+
+import io.mehow.laboratory.Feature
+import io.mehow.laboratory.FeatureFactory
+import java.lang.Class
+import kotlin.Suppress
+import kotlin.collections.Set
+import kotlin.collections.setOf
+
+internal fun FeatureFactory.Companion.featureGenerated(): FeatureFactory = GeneratedFeatureFactory
+
+private object GeneratedFeatureFactory : FeatureFactory {
+  @Suppress("UNCHECKED_CAST")
+  override fun create(): Set<Class<out Feature<*>>> = setOf(
+    Class.forName("io.mehow.laboratory.sample.FeatureA"),
+    Class.forName("io.mehow.laboratory.sample.FeatureB"),
+    Class.forName("io.mehow.laboratory.sample.FeatureC")
+  ) as Set<Class<Feature<*>>>
+}
+
+

Feature flag sources factory

+

If you want to group all feature flag sources similar to feature flags, you can use featureSourceFactory() function that collects them.

+
laboratory {
+  packageName = "io.mehow.laboratory.sample"
+
+  featureSourceFactory()
+
+  feature("FeatureA") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+
+    withSource(Remote)
+  }
+
+  feature("FeatureB") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+
+    withSource(Remote)
+  }
+}
+
+

This uses the generateFeatureSourceFactory Gradle task that generates the code below.

+
package io.mehow.laboratory.sample
+
+import io.mehow.laboratory.Feature
+import io.mehow.laboratory.FeatureFactory
+import java.lang.Class
+import kotlin.Suppress
+import kotlin.collections.Set
+import kotlin.collections.setOf
+
+internal fun FeatureFactory.Companion.featureSourceGenerated(): FeatureFactory =
+    GeneratedFeatureSourceFactory
+
+private object GeneratedFeatureSourceFactory : FeatureFactory {
+  @Suppress("UNCHECKED_CAST")
+  override fun create(): Set<Class<out Feature<*>>> = setOf(
+    Class.forName("io.mehow.laboratory.sample.FeatureA${'$'}Source"),
+    Class.forName("io.mehow.laboratory.sample.FeatureB${'$'}Source")
+  ) as Set<Class<Feature<*>>>
+}
+
+

Feature flag option factory

+

The generation of an option factory is useful when you want to control local feature flag options remotely. Option factory aggregates all feature flags and recognizes them either by a fully qualified class name or an optional key property on a feature flag. Keys must be unique and cannot match fully qualified class names of other feature flags.

+

+
apply plugin: "io.mehow.laboratory"
+
+laboratory {
+  packageName = "io.mehow.laboratory.sample"
+
+  optionFactory()
+
+  feature("FeatureA") {
+    key = "FeatureA"
+
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+
+  feature("FeatureB") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+
+  feature("FeatureC") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+}
+
+

This uses the generateOptionFactory Gradle task that generates the code below.

+
package io.mehow.laboratory.sample
+
+import io.mehow.laboratory.Feature
+import io.mehow.laboratory.OptionFactory
+
+internal fun OptionFactory.Companion.generated(): OptionFactory = GeneratedOptionFactory
+
+private object GeneratedOptionFactory : OptionFactory {
+  override fun create(key: String, name: String): Feature<*>? = when (key) {
+    "FeatureA" -> when (name) {
+      "Enabled" -> FeatureA.Enabled
+      "Disabled" -> FeatureA.Disabled
+      else -> null
+    }
+    "io.mehow.laboratory.sample.FeatureB" -> when (name) {
+      "Enabled" -> FeatureB.Enabled
+      "Disabled" -> FeatureB.Disabled
+      else -> null
+    }
+    "io.mehow.laboratory.sample.FeatureC" -> when (name) {
+      "Enabled" -> FeatureC.Enabled
+      "Disabled" -> FeatureC.Disabled
+      else -> null
+    }
+    else -> null
+  }
+}
+
+

Multi-module support

+

The Gradle plugin was written with support for multi-module projects in mind.

+
+

Tip

+

Check the sample with demo configuration.

+
+
.
+├─ module-a
+│  └─ build.gradle
+├─ module-b
+│  └─ build.gradle
+├─ module-app
+│  └─ build.gradle
+├─ build.gradle
+└─ settings.gradle
+
+

A Laboratory setup for a Gradle project like above could look like this. Configuration of the Android Gradle plugin or any other dependencies is omitted for brevity.

+
// module-a
+plugins {
+  id "org.jetbrains.kotlin.jvm"
+  id "io.mehow.laboratory"
+}
+
+laboratory {
+  packageName = "com.sample.a"
+
+  feature("Authentication") {
+    withDefaultOption("Password")
+    withOption("Fingerprint")
+    withOption("Retina")
+    withOption("Face")
+
+    withSource("Firebase")
+    withSource("Aws")
+  }
+
+  feature("AllowScreenshots") {
+    withOption("Enabled")
+    withDefaultOption("Disabled")
+  }
+}
+
+
// module-b
+plugins {
+  id "org.jetbrains.kotlin.jvm"
+  id "io.mehow.laboratory"
+}
+
+laboratory {
+  packageName = "com.sample.b"
+
+  feature("DistanceAlgorithm") {
+    isPublic = false
+
+    withDefaultOption("Euclidean")
+    withOption("Jaccard")
+    withOption("Cosine")
+    withOption("Edit")
+    withOption("Hamming")
+
+    withSource("Firebase")
+    withDefaultSource("Azure")
+  }
+}
+
+dependencies {
+  implementation project(":module-a")
+}
+
+
// module-app
+plugins {
+  id "com.android.application"
+  id "org.jetbrains.kotlin.android"
+  id "io.mehow.laboratory"
+}
+
+laboratory {
+  packageName = "com.sample"
+  sourcedStorage()
+  featureFactory()
+
+  dependency(project(":module-a"))
+  dependency(project(":module-b"))
+}
+
+dependencies {
+  implementation project(":module-b")
+}
+
+

This setup shows that each module can define its feature flags that do not have to be exposed outside. In this scenario, module-app is responsible only for gluing together all feature flags so that Laboratory instances are aware of feature flag sources and the QA module. It should then deliver the correct Laboratory to modules via dependency injection. In order to include feature flags during generation of factories, their modules need to be added with dependency function.

+

Full configuration

+

Below is the full configuration of the Gradle plugins.

+
laboratory {
+  // Sets namespace of generated features and factories. Empty by default.
+  packageName = "io.mehow.sample"
+
+  // Informs plugin to create 'enum class SomeFeature' during the generation period.
+  feature("SomeFeature") {
+    // Used for option factory lookup. No value by default.
+    key = "SomeFeatureKey"
+
+    // Overrides globally declared namespace. No value by default.
+    packageName = "io.mehow.sample.feature"
+
+    // Adds a description to this feature that can be used for more context.
+    description = "Feature description"
+
+    // Sets the visibility of a feature flag to be either 'public' or 'internal'. 'true' by default.
+    isPublic = false
+
+    // Deprecates a feature flag. `DeprecationLevel` argument is optional and uses `DeprecationLevel.Warning` by default.
+    // Add the class to the import list in your Gradle script to avoid typing the whole package name.
+    deprecated("Deprecation message", io.mehow.laboratory.gradle.DeprecationLevel.Hidden)
+
+    // Informs plugin to add 'ValueA' option to the generated feature flag and set it as a default option.
+    // Exactly one of the feature options must be set with this function.
+    withDefaultOption("ValueA")
+
+    // Informs plugin to add 'ValueB' option to the generated feature flag.
+    withOption("ValueB")
+
+    // Informs plugin to add 'Firebase' option to the list of sources controlling this flag.
+    // Adding any source automatically adds the 'Local' option to the source enum.
+    // Any custom 'Local' sources are ignored by the plugin.
+    withSource("Firebase")
+
+    // Informs plugin to add 'Aws' option to the list of sources controlling this flag and to set a default option.
+    // At most, one of the source options can be set with this function.
+    // By default, 'Local' sources are considered to be default options.
+    withDefaultSource("Aws")
+
+    // Same as `withDefaultOption(option)` without lambda except that it generates supervised feature flags
+    // defined in the lambda.
+    withDefaultOption("Option") { option ->
+      option.feature("SupervisedFeature") {
+        // recursive feature generation
+      }
+    }
+
+    // Same as `withOption(option)` without lambda except that it generates supervised feature flags
+    // defined in the lambda.
+    withOption("Option") { option ->
+      option.feature("SupervisedFeature") {
+        // recursive feature generation
+      }
+    }
+  }
+
+  // Informs plugin to create 'enum class SomeFeature' during the generation period with two options.
+  // 'Enabled' and 'Disabled' and uses 'Enabled' as the default one.
+  enabledFeature("SomeFeature") {
+    // Uses the same options as feature() block except for `withOption()` and `withDefaultOption()`.
+
+    withEnabled { option ->
+      option.feature("SupervisedFeature") {
+        // recursive feature generation
+      }
+    }
+  }
+
+  // Informs plugin to create 'enum class SomeFeature' during the generation period with two options.
+  // 'Enabled' and 'Disabled' and uses 'Disabled' as the default one.
+  disabled("SomeFeature") {
+    // Uses the same options as feature() block except for `withOption()` and `withDefaultOption()`.
+
+    withEnabled { option ->
+      option.feature("SupervisedFeature") {
+        // recursive feature generation
+      }
+    }
+  }
+
+  // Configures feature flags storage. Useful when feature flags have multiple sources.
+  sourcedStorage {
+    // Overrides globally declared namespace. No value by default.
+    packageName = "io.mehow.sample.storage"
+
+    // Sets visibility of a storage extension function to be either 'public' or 'internal'. 'false' by default.
+    isPublic = true
+  }
+
+  // Configures option factory. Useful for integration with remote service such as Firebase.
+  optionFactory {
+    // Overrides globally declared namespace. No value by default.
+    packageName = "io.mehow.sample.factory"
+
+    // Sets visibility of a factory extension function to be either 'public' or 'internal'. 'false' by default.
+    isPublic = true
+  }
+
+  // Configures feature flags factory. Useful for the QA module configuration.
+  featureFactory {
+    // Overrides globally declared namespace. No value by default.
+    packageName = "io.mehow.sample.factory"
+
+    // Sets visibility of a factory extension function to be either 'public' or 'internal'. 'false' by default.
+    isPublic = true
+  }
+
+  // Configures feature flag sources factory.
+  featureSourceFactory {
+    // Overrides globally declared namespace. No value by default.
+    packageName = "io.mehow.sample.factory"
+
+    // Sets visibility of a factory extension function to be either 'public' or 'internal'. 'false' by default.
+    isPublic = true
+  }
+
+  // Includes feature flags that are used for generation of feature factories, sourced storage and option factory.
+  dependency(project(":some-project"))
+  // By default dependency contributes to all declared generators but it can be selectively applied
+  // by passing a contribution list.
+  dependency(project(":some-project"), [DependencyContribution.FeatureFactory, DependencyContribution.OptionFactory])
+  // If typesafe project accessors are enabled.
+  dependency(projects.someProject)
+}
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/images/hyperion_screenshot.jpg b/images/hyperion_screenshot.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b57a67808a5f80fa784c2379b8660a613bcb075 GIT binary patch literal 33157 zcmeFZcTkgU_bwXj4J-&21S}u|0v3vN6a@k4y{ib)QL5CSsE7z?Xi8T)0iv`30ivRy zAiabh>7CF*351;WynFx7%x};6@$1L_YPwqdGb7WS?gMBUF*8v5G@U5=6xsk zp-?DhmD@LUP^j(j>rT|3UGOrmEmj0CJKS!l=t

JY29^#fg(|uJ%yc0|@HHCe!%Ny5)za(pS!v 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 z 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

9?yA?604M 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 z

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 literal 0 HcmV?d00001 diff --git a/images/laboratory_logo.svg b/images/laboratory_logo.svg new file mode 100644 index 000000000..79da7f9e4 --- /dev/null +++ b/images/laboratory_logo.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/laboratory_logo_menu.svg b/images/laboratory_logo_menu.svg new file mode 100644 index 000000000..6a94769d6 --- /dev/null +++ b/images/laboratory_logo_menu.svg @@ -0,0 +1,6 @@ + + + diff --git a/index.html b/index.html new file mode 100644 index 000000000..745106342 --- /dev/null +++ b/index.html @@ -0,0 +1,602 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Laboratory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

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

Laboratory ⚗️

+

Laboratory

+

A feature flags management library for multi-module Kotlin Android projects. Laboratory offers:

+
    +
  • Encapsulation: Different feature flags can freely live in separate Gradle modules without being exposed outside.
  • +
  • Type safety: Feature flags are represented with concrete types instead of booleans or grouped enums.
  • +
  • A/B/n testing: Feature flags don’t have to be constrained to provide only a binary choice. They can have as many states as you’d like.
  • +
  • Multiple sources: Feature flags can have different sources used for their current options. For example, you can have a feature flag that takes its option either from a local source or from any number of remote sources like, for instance, Firebase or Azure.
  • +
  • QA integration: Laboratory offers great QA capabilities and easy integration with popular tools. It comes with an out-of-the-box Hyperion plugin.
  • +
  • Persistence ignorance: Laboratory does not care how you want to store your feature flags. It provides implementations for most common scenarios, but you can always use an implementation for your custom storage mechanism.
  • +
  • Testing support: The in-memory implementation can be used as a drop-in substitute for Laboratory instances in tests.
  • +
  • Coroutines support: Changes to feature flags can be observed via Flow. Options reads and writes are made with suspend functions, but you can always opt-in to a blocking equivalent of I/O functions.
  • +
+

TLDR

+

First, you need to define your feature flags.

+
enum class AuthType : Feature<AuthType> {
+  None,
+  Fingerprint,
+  Retina,
+  Face;
+
+  public override val defaultOption get() = Fingerprint
+}
+
+

Once you have your feature flags defined, you can start using them in the application.

+
suspend fun main() {
+  // A high-level API for interaction with feature flags
+  val laboratory = Laboratory.inMemory()
+
+  // Set AuthType option to Fingerprint
+  val success = laboratory.setOption(AuthType.Fingerprint)
+
+  // Check what is the current option of AuthType
+  val currentAuthType = laboratory.experiment<AuthType>()
+
+  // Check if the current option of AuthType is equal to Face
+  val isFaceAuth = laboratory.experimentIs(AuthType.Face)
+
+  // Observe changes to the AuthType feature flag
+  laboratory.observe<AuthType>()
+      .onEach { option -> println("AuthType: $option") }
+      .launchIn(GlobalScope)
+}
+
+

Requirements

+

Laboratory requires default methods generation. You can do this by adding a compiler flag in a build.gradle file.

+
android {
+  kotlinOptions {
+    freeCompilerArgs += [
+        "-Xjvm-default=all",
+    ]
+  }
+}
+
+

R8

+

Laboratory ships with R8 rules and doesn’t require any extra configuration.

+

Get Laboratory

+

Laboratory is published to Maven Central Repository.

+
repositories {
+  mavenCentral()
+}
+
+dependencies {
+  implementation "io.mehow.laboratory:laboratory:1.1.0"
+}
+
+

Snapshots of the development version are available on Sonatype’s snapshots repository.

+

Here is the list of all available artifacts that Laboratory library provides.

+
    +
  • io.mehow.laboratory:laboratory:1.1.0: Core of the library. Defines classes and interfaces that you can interact with from your application code. It also provides R8 rules.
  • +
  • io.mehow.laboratory:laboratory-shared-preferences:1.1.0: Provides implementation of FeatureStorage based on SharedPreferences.
  • +
  • io.mehow.laboratory:laboratory-data-store:1.1.0: Provides implementation of FeatureStorage based on Jetpack DataStore.
  • +
  • io.mehow.laboratory:laboratory-inspector:1.1.0: QA module that allows users to preview all features and change them at runtime from one place.
  • +
  • io.mehow.laboratory:laboratory-hyperion-plugin:1.1.0: QA module that integrates laboratory-inspector with Hyperion.
  • +
  • io.mehow.laboratory:laboratory-gradle-plugin:1.1.0: Gradle plugin for feature flags generation and other quality of life improvements. It is highly recommended to use it instead of manual class management.
  • +
+

License

+
Copyright 2020 Michał Sikora
+
+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.
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/qa-module/index.html b/qa-module/index.html new file mode 100644 index 000000000..55e79277c --- /dev/null +++ b/qa-module/index.html @@ -0,0 +1,642 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + QA module - Laboratory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

QA module

+

It is very often desirable to have the option of configuring feature flag options at runtime. Laboratory addresses this problem with its QA modules.

+

Inspector

+

Feature flags inspection is available through the laboratory-inspector artifact. LaboratoryActivity is an Activity that enables inspection and modifications of feature flags.

+

Inspector

+

Inspector displays feature flags as cards and their options on chips. Active options of feature flags are marked with a highlight color. A local option of a feature flag can be changed by tapping on a chip. Chips that do not use Local sources cannot have their options changed. If a feature flag has multiple sources available, they can be switched from a drop down menu.

+

Feature flags (including sources) can be reset to their default options with a button in an action bar.

+

Configuration

+

Before LaboratoryActivity can be started, it has to be configured with an instance of Laboratory and at least one instance of FeatureFactory. FeatureFactory is an interface that should gather feature flags that are logically grouped together. Logical grouping can be different for each application, but in most cases, all feature flags in the project belong to a single unit. Scenarios, when you might want to split feature flags, are for example:

+
    +
  • Feature flags that do not belong to your project and are exposed to you from an external library.
  • +
  • Abundance of feature flags and a need to increase the readability of the inspector interface by separating feature flags into custom categories.
  • +
+
+

Tip

+

A lot of the boilerplate code presented here can be generated with the Gradle plugin. It is highly recommended to rely on the plugin instead of handwriting the code.

+
+
val sourcedFeatureStorage = FeatureStorage.sourced(
+  localSource = FeatureStorage.inMemory(),
+  remoteSources = mapOf(
+    "Firebase" to FeatureStorage.inMemory(),
+    "Aws" to FeatureStorage.inMemory(),
+    "Azure" to FeatureStorage.inMemory(),
+  ),
+)
+val laboratory = Laboratory.create(sourcedFeatureStorage)
+
+LaboratoryActivity.configure(
+  laboratory = laboratory,
+  featureFactory = CustomFeatureFactory,
+)
+LaboratoryActivity.start(context)
+
+object CustomFeatureFactory : FeatureFactory {
+  override fun create(): Set<Class<out Feature<*>>> = setOf(
+    AllowScreenshots::class.java,
+    Authentication::class.java,
+    PowerSource::class.java,
+    DistanceAlgorithm::class.java,
+    LogType::class.java,
+  )
+}
+
+enum class AllowScreenshots : Feature<AllowScreenshots> {
+  Enabled,
+  Disabled;
+
+  public override val defaultOption get() = Disabled
+
+  override val description: String = "Enables or disables screenshots during a video chat"
+}
+
+enum class Authentication : Feature<Authentication> {
+  Password,
+  Fingerprint,
+  Retina,
+  Face;
+
+  public override val defaultOption get() = Password
+
+  override val source = Source::class.java
+
+  enum class Source : Feature<Source> {
+    Local,
+    Firebase,
+    Aws;
+
+    public override val defaultOption get() = Local
+  }
+}
+
+enum class DistanceAlgorithm : Feature<DistanceAlgorithm> {
+  Euclidean,
+  Jaccard,
+  Cosine,
+  Edit,
+  Hamming;
+
+  public override val defaultOption get() = Euclidean
+
+  @Suppress("UNCHECKED_CAST")
+  override val source: Class<Feature<*>> = Source::class.java as Class<Feature<*>>
+
+  override val description: String = "Algorithm used for destination distance calculations"
+
+  enum class Source : Feature<Source> {
+    Local,
+    Firebase,
+    Azure;
+
+    public override val defaultOption get() = Azure
+  }
+}
+
+enum class LogType : Feature<LogType> {
+  Verbose,
+  Debug,
+  Info,
+  Warning,
+  Error;
+
+  public override val defaultOption get() = Info
+}
+
+enum class PowerSource : Feature<PowerSource> {
+  Coal,
+  Wind,
+  Solar,
+  Nuclear,
+  ColdFusion;
+
+  public override val defaultOption get() = Solar
+
+  @Suppress("UNCHECKED_CAST")
+  override val source: Class<Feature<*>> = Source::class.java as Class<Feature<*>>
+
+  enum class Source : Feature<Source> {
+    Local,
+    Firebase;
+
+    public override val defaultOption get() = Firebase
+  }
+}
+
+

Deprecation

+

You can configure how deprecated feature flags will be represented in the QA module. To do this you need to pass additional parameters to the Configuration builder.

+
val configuration = LaboratoryActivity.Configuration.builder()
+    .laboratory(laboratory)
+    .featureFactories(mapOf("Features" to featureFactory))
+    .deprecationPhenotypeSelector { deprecationLevel -> DeprecationPhenotype.Strikethrough }
+    .deprecationAlignmentSelector { deprecationLevel -> DeprecationAlignment.Bottom }
+    .build()
+LaboratoryActivity.configure(configuration)
+
+

Hyperion

+

If you use Hyperion you can easily integrate Laboratory by adding the laboratory-hyperion-plugin artifact to your dependencies. This will put an item in Hyperion’s debug menu.

+

Hyperion

+

If you’d like to position the Laboratory menu item in a different place on the menu, you can override the string id resource.

+
<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <string name="io_mehow_laboratory_plugin_id" translatable="false">!Laboratory</string>
+</resources>
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/releasing/index.html b/releasing/index.html new file mode 100644 index 000000000..ae8fb18e8 --- /dev/null +++ b/releasing/index.html @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Releasing - Laboratory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

Releasing

+

Versioning

+
    +
  1. Run the prepare release script and bump the desirable version part.
  2. +
  3. If there are no errors git push && git push --tags.
  4. +
  5. Wait for the CI server to upload the artifacts.
  6. +
  7. Visit Sonatype Nexus and promote the artifacts.
  8. +
+

Documentation updates

+

Website documentation lives under /docs directory and is deployed with MkDocs using Material Theme. A new site is built and published for the latest commits on the trunk branch.

+

If you want to test the website locally before pushing changes, you need to follow these steps.

+

Make sure you have Python 3 and pip installed.

+
$ python --version
+Python 3.8.5
+
+$ pip --version
+pip 20.2.4
+
+

Install MkDocs, Material Theme and MkDocs Video.

+
$ pip install mkdocs mkdocs-material mkdocs-video
+$ mkdocs --version
+mkdocs, version 1.1.2
+
+

Navigate to the library directory and run the site locally.

+
$ mkdocs serve
+INFO    -  Building documentation...
+INFO    -  Cleaning site directory
+INFO    -  Documentation built in 0.73 seconds
+[I 201026 22:51:56 server:335] Serving on http://127.0.0.1:8000
+INFO    -  Serving on http://127.0.0.1:8000
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..95af4e40e --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +mkdocs-video diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 000000000..01662b8aa --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Quick start","text":""},{"location":"#laboratory","title":"Laboratory \u2697\ufe0f","text":"

A feature flags management library for multi-module Kotlin Android projects. Laboratory offers:

  • Encapsulation: Different feature flags can freely live in separate Gradle modules without being exposed outside.
  • Type safety: Feature flags are represented with concrete types instead of booleans or grouped enums.
  • A/B/n testing: Feature flags don\u2019t have to be constrained to provide only a binary choice. They can have as many states as you\u2019d like.
  • Multiple sources: Feature flags can have different sources used for their current options. For example, you can have a feature flag that takes its option either from a local source or from any number of remote sources like, for instance, Firebase or Azure.
  • QA integration: Laboratory offers great QA capabilities and easy integration with popular tools. It comes with an out-of-the-box Hyperion plugin.
  • Persistence ignorance: Laboratory does not care how you want to store your feature flags. It provides implementations for most common scenarios, but you can always use an implementation for your custom storage mechanism.
  • Testing support: The in-memory implementation can be used as a drop-in substitute for Laboratory instances in tests.
  • Coroutines support: Changes to feature flags can be observed via Flow. Options reads and writes are made with suspend functions, but you can always opt-in to a blocking equivalent of I/O functions.
"},{"location":"#tldr","title":"TLDR","text":"

First, you need to define your feature flags.

enum class AuthType : Feature<AuthType> {\nNone,\nFingerprint,\nRetina,\nFace;\n\npublic override val defaultOption get() = Fingerprint\n}\n

Once you have your feature flags defined, you can start using them in the application.

suspend fun main() {\n// A high-level API for interaction with feature flags\nval laboratory = Laboratory.inMemory()\n\n// Set AuthType option to Fingerprint\nval success = laboratory.setOption(AuthType.Fingerprint)\n\n// Check what is the current option of AuthType\nval currentAuthType = laboratory.experiment<AuthType>()\n\n// Check if the current option of AuthType is equal to Face\nval isFaceAuth = laboratory.experimentIs(AuthType.Face)\n\n// Observe changes to the AuthType feature flag\nlaboratory.observe<AuthType>()\n.onEach { option -> println(\"AuthType: $option\") }\n.launchIn(GlobalScope)\n}\n
"},{"location":"#requirements","title":"Requirements","text":"

Laboratory requires default methods generation. You can do this by adding a compiler flag in a build.gradle file.

android {\nkotlinOptions {\nfreeCompilerArgs += [\n\"-Xjvm-default=all\",\n]\n}\n}\n
"},{"location":"#r8","title":"R8","text":"

Laboratory ships with R8 rules and doesn\u2019t require any extra configuration.

"},{"location":"#get-laboratory","title":"Get Laboratory","text":"

Laboratory is published to Maven Central Repository.

repositories {\nmavenCentral()\n}\n\ndependencies {\nimplementation \"io.mehow.laboratory:laboratory:1.1.0\"\n}\n

Snapshots of the development version are available on Sonatype\u2019s snapshots repository.

Here is the list of all available artifacts that Laboratory library provides.

  • io.mehow.laboratory:laboratory:1.1.0: Core of the library. Defines classes and interfaces that you can interact with from your application code. It also provides R8 rules.
  • io.mehow.laboratory:laboratory-shared-preferences:1.1.0: Provides implementation of FeatureStorage based on SharedPreferences.
  • io.mehow.laboratory:laboratory-data-store:1.1.0: Provides implementation of FeatureStorage based on Jetpack DataStore.
  • io.mehow.laboratory:laboratory-inspector:1.1.0: QA module that allows users to preview all features and change them at runtime from one place.
  • io.mehow.laboratory:laboratory-hyperion-plugin:1.1.0: QA module that integrates laboratory-inspector with Hyperion.
  • io.mehow.laboratory:laboratory-gradle-plugin:1.1.0: Gradle plugin for feature flags generation and other quality of life improvements. It is highly recommended to use it instead of manual class management.
"},{"location":"#license","title":"License","text":"
Copyright 2020 Micha\u0142 Sikora\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n
"},{"location":"changelog/","title":"Changelog","text":""},{"location":"changelog/#changelog","title":"Changelog","text":"

All notable changes to this project will be documented in this document.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

"},{"location":"changelog/#unreleased","title":"Unreleased","text":""},{"location":"changelog/#added","title":"Added","text":"
  • Gradle tasks are now cacheable.
  • Support for typesafe project accessors when declaring dependencies.
  • Shorthand for creating binary flags.
    laboratory {\n// Generates 'Feature' with two options - 'Enabled and 'Disabled'. 'Enabled' is the default one.\nenabledFeature(\"Feature\")\n// Generates 'Feature' with two options - 'Enabled and 'Disabled'. 'Disabled' is the default one.\ndisabledFeature(\"Feature\")\n}\n
  • Dependencies can now selectively contribute to generation process.
    laboratory {\nfeatureFactory()\nfeatureSourceFactory()\nsourcedStorage()\noptionFactory()\n\ndependency(project(\":feature\"), [\nDependencyContribution.FeatureFactory,\nDependencyContribution.FeatureSourceFactory, DependencyContribution.OptionFactory, DependencyContribution.SourcedStorage,\n])\n}\n
"},{"location":"changelog/#changed","title":"Changed","text":"
  • Gradle tasks are now always registered when plugin is applied in a project. If there is nothing to generate tasks will clear their respective output directories.
  • Upgrade to Kotlin 1.9.24.
  • Upgrade to Coroutines 1.8.1.
  • Upgrade to Gradle 8.7.
  • Upgrade to AGP to 8.4.1.
  • Upgrade to Wire 4.9.9.
  • Upgrade to KotlinPoet 1.16.0.
  • Upgrade to DataStore 1.1.1.
  • Upgrade to ViewPager2 1.3.2.
  • Upgrade to ViewModel-ktx 2.8.0.
  • Upgrade to Fragment-ktx 1.7.1.
  • Upgrade to RecyclerView 1.3.2.
  • Upgrade to Material 1.12.0.
  • Upgrade to Hyperion 0.9.38.
  • Downgrade target and source compatibilities versions to Java 11.
  • Change compile and target SDK to 34.
"},{"location":"changelog/#fixed","title":"Fixed","text":"
  • Gradle tasks are now correctly marked as internal.
"},{"location":"changelog/#110-2023-06-13","title":"1.1.0 - 2023-06-13","text":""},{"location":"changelog/#changed_1","title":"Changed","text":"
  • Upgrade to Kotlin 1.8.21.
  • Upgrade to Coroutines 1.6.4.
  • Upgrade to Gradle 8.1.1.
  • Upgrade to Wire 4.7.0.
  • Upgrade to KotlinPoet 1.14.2.
  • Upgrade to Hyperion 0.9.37.
  • Upgrade to AppCompat 1.6.1.
  • Upgrade to ViewModel-ktx 2.6.1.
  • Upgrade to Fragment-ktx 1.5.7.
  • Upgrade to RecyclerView 1.3.0.
  • Upgrade to Material 1.9.0.
  • Upgrade target and source compatibilities versions to Java 17.
  • Change compile and target SDK to 33.
"},{"location":"changelog/#103-2022-10-01","title":"1.0.3 - 2022-10-01","text":""},{"location":"changelog/#fixed_1","title":"Fixed","text":"
  • Generating feature flags and related classes to empty Kotlin source sets in Kotlin 1.7.20.
"},{"location":"changelog/#102-2022-09-29","title":"1.0.2 - 2022-09-29","text":""},{"location":"changelog/#fixed_2","title":"Fixed","text":"
  • Fixed IllegalArgumentException: Did not find Kotlin source set after upgrading to Kotlin 1.7.20.
"},{"location":"changelog/#101-2022-06-21","title":"1.0.1 - 2022-06-21","text":""},{"location":"changelog/#added_1","title":"Added","text":"
  • Gradle configuration cache support.
"},{"location":"changelog/#removed","title":"Removed","text":"
  • CoreKtx dependency.
"},{"location":"changelog/#100-2021-02-06","title":"1.0.0 - 2021-02-06","text":""},{"location":"changelog/#added_2","title":"Added","text":"
  • setOptions(options) overload which accepts collection instead of varargs.
"},{"location":"changelog/#removed_1","title":"Removed","text":"
  • ConstraintLayout dependency.
  • DynamicAnimation dependency.
"},{"location":"changelog/#100-rc2-2021-12-28","title":"1.0.0-rc2 - 2021-12-28","text":""},{"location":"changelog/#changed_2","title":"Changed","text":"
  • SharedPreferencesFeatureStorage no marked as experimental due to coroutines.
  • Upgrade to Kotlin 1.6.10.
  • Upgrade to Coroutines 1.6.0.
  • Upgrade to Wire 4.0.1.
"},{"location":"changelog/#fixed_3","title":"Fixed","text":"
  • Handle usage of deprecated features in a generated OptionFactory.
"},{"location":"changelog/#removed_2","title":"Removed","text":"
  • Builders for generator models. Models are now created via constructors and throw if data is invalid.
  • GenerationFailure interface.
  • Arrow dependency.
"},{"location":"changelog/#100-rc1-2021-12-22","title":"1.0.0-rc1 - 2021-12-22","text":""},{"location":"changelog/#added_3","title":"Added","text":"
  • Multi-module setup no longer includes other modules implicitly. Instead each module needs to be included via dependency function in Gradle.
    laboratory {\nfeatureFactory()\n\n// Before, these were included implicitly.\ndependency(project(\":module-a\"))\ndependency(project(\":module-b\"))\n}\n
"},{"location":"changelog/#changed_3","title":"Changed","text":"
  • Upgrade Android target and compile SDK to 31.
  • Upgrade to LifecycleViewmodelKtx 2.4.0.
  • Upgrade to KotlinPoet 1.10.2.
  • Upgrade to Wire 4.0.0.
  • Upgrade to Kotlin 1.6.0.
  • Upgrade to ConstraintLayout 2.1.2.
  • Upgrade to FragmentKtx 1.4.0.
  • Upgrade to AppCompat 1.4.0.
"},{"location":"changelog/#removed_3","title":"Removed","text":"
  • Groovy DSL introduced in 0.9.0 for adding feature flags.
  • projectFilter properties from Gradle plugin. Use explicit dependencies instead.
  • Deprecated API.
"},{"location":"changelog/#fixed_4","title":"Fixed","text":"
  • Overrides of sources in DefaultOptionFactory are now respected by Laboratory - #220.
"},{"location":"changelog/#0140-2021-10-11","title":"0.14.0 - 2021-10-11","text":""},{"location":"changelog/#added_4","title":"Added","text":"
  • Better integration with remote sources, like Firebase, via OptionFactory interface. It creates feature options based on a feature key and an option name.
  • Code generation of option factory via Gradle plugin.
"},{"location":"changelog/#changed_4","title":"Changed","text":"
  • Make Feature and other related classes covariant.
  • FeatureStorage functions are no longer parameterized over Feature. They accept raw class type instead.
  • Generator and Gradle plugin no longer validate package names, duplicates and other things that are checked by compiler.
  • Model builders accept now ClassName in constructor.
  • Mark SharedPreferencesFeatureStorage with ExperimentalCoroutinesApi annotation.
  • Upgrade to Kotlin 1.5.31.
  • Upgrade to Material 1.4.0.
  • Upgrade to CoreKtx 1.6.0.
  • Upgrade to DataStore 1.0.0.
  • Upgrade to AGP 4.2.2.
  • Upgrade to Hyperion 0.9.34.
  • Upgrade to FragmentKtx 1.3.6.
  • Upgrade to AppCompat 1.3.1.
  • Upgrade to ConstraintLayout 2.1.1.
  • Upgrade to ArrowKt 1.0.0.
  • Upgrade to Coroutines 1.5.2.
  • Upgrade to KotlinPoet 1.10.1.
"},{"location":"changelog/#deprecated","title":"Deprecated","text":"
  • FeatureStorage.Companion.sharedPreferences(Context) function. Use overload that accepts SharedPreferences instead.
  • FeatureStorage.Companion.dataStore(() -> File) function. Use overload that accepts DataStore instead.
  • FeatureStorage.Companion.dataStore(Context, String) function. Use overload that accepts DataStore instead.
  • generate() methods on generation models. Use prepare() and operate on FileSpec directly instead.
"},{"location":"changelog/#removed_4","title":"Removed","text":"
  • Dependency on Kyrie.
  • Dependency on JCenter.
"},{"location":"changelog/#0131-2021-06-27","title":"0.13.1 - 2021-06-27","text":""},{"location":"changelog/#changed_5","title":"Changed","text":"
  • Upgrade to Kotlin 1.5.20.
  • Upgrade to RecyclerView 1.2.1.
  • Upgrade to FragmentKtx 1.3.5.
  • Upgrade to DataStore 1.0.0-beta02.
  • Upgrade to KotlinPoet 1.9.0.
  • Upgrade to CoreKtx 1.5.0.
  • Upgrade to AppCompat 1.3.0.
"},{"location":"changelog/#0130-2021-05-17","title":"0.13.0 - 2021-05-17","text":""},{"location":"changelog/#changed_6","title":"Changed","text":"
  • Drop deprecated @JvmDefault and switch to JVM default modes.
  • Upgrade to Kotlin 1.5.0.
  • Upgrade to Coroutines 1.5.0.
  • Upgrade to AGP 4.2.1.
  • Upgrade to KotlinPoet 1.8.0.
  • Upgrade to RecyclerView 1.2.0.
  • Upgrade to Hyperion 0.9.32.
  • Upgrade to FragmentKtx 1.3.3.
  • Upgrade to DataStore 1.0.0-beta01.
"},{"location":"changelog/#0121-2021-03-28","title":"0.12.1 - 2021-03-28","text":""},{"location":"changelog/#added_5","title":"Added","text":"
  • Indication that an option is a supervisor. If an option supervises features it has an eye icon next to it. List of supervised features is available after long pressing a chip.
  • Navigation from supervised feature to supervisor.
  • Navigation from supervisor to supervised feature.
  • Amount of offscreen feature sections in inspector can be controlled with LaboratoryActivity.Configuration.OffscreenSectionsBehavior. Default is unlimited.
"},{"location":"changelog/#changed_7","title":"Changed","text":"
  • Upgrade to Kotlin 1.4.32.
  • Upgrade to LifecycleViewmodelKtx 2.3.1.
  • Upgrade to FragmentKtx 1.3.2.
  • Upgrade to Wire 3.7.0.
"},{"location":"changelog/#0120-2021-03-21","title":"0.12.0 - 2021-03-21","text":""},{"location":"changelog/#added_6","title":"Added","text":"
  • Gradle plugin generates sourcedBuilder() extension function for SourcedFeatureStorage that returns custom builder with steps for each source. This makes changes to sources compile time safe.
  • Show feature\u2019s supervisor option in inspector \u2013 #95.
"},{"location":"changelog/#changed_8","title":"Changed","text":"
  • Upgrade to Coroutines 1.4.3.
  • Upgrade to AGP 4.1.3.
"},{"location":"changelog/#deprecated_1","title":"Deprecated","text":"
  • sourcedGenerated() extension function generated by Gradle plugin.
"},{"location":"changelog/#0110-2021-03-11","title":"0.11.0 - 2021-03-11","text":""},{"location":"changelog/#changed_9","title":"Changed","text":"
  • Use proto3 for FeatureFlags definition.
  • Upgrade to DataStore 1.0.0-alpha08.
  • Upgrade to Kotlin 1.4.31.
  • Upgrade to Wire 3.6.1.
  • Upgrade to FragmentKtx 1.3.1.
"},{"location":"changelog/#0100-2021-02-18","title":"0.10.0 - 2021-02-18","text":""},{"location":"changelog/#added_7","title":"Added","text":"
  • Parent\u2013child relationship to Feature. This relationship is controlled with a Feature.supervisorOption property. Whenever supervisor has its option different from this value then the supervised feature flag cannot return any other option than a default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised. This relationship is recursive meaning that grandparents control grandchildren indirectly.
  • Code generation of supervisor options via Gradle plugin.
"},{"location":"changelog/#changed_10","title":"Changed","text":"
  • Gradle plugin no longer changes implicit package name multiple times. Only last value that was set is applied in configuration.
  • Upgrade to DataStore 1.0.0-alpha06.
  • Upgrade to AGP 4.1.2.
  • Upgrade to Kotlin 1.4.30.
  • Upgrade to Wire 3.6.0.
  • Upgrade to Material 1.3.0.
  • Upgrade to FragmentKtx 1.3.0.
  • Upgrade to LifecycleViewmodelKtx 2.3.0.
  • Upgrade to Hyperion 0.9.31.
"},{"location":"changelog/#fixed_5","title":"Fixed","text":"
  • Search icon not animating on Android below SDK 24.
"},{"location":"changelog/#deprecated_2","title":"Deprecated","text":"
  • DataStore custom builder and builder factory methods. Factory method that accepts DataStore directly should be used instead.
"},{"location":"changelog/#097-2020-12-15","title":"0.9.7 - 2020-12-15","text":""},{"location":"changelog/#changed_11","title":"Changed","text":"
  • DeprecationLevel.Hidden is no longer deprecated. It was a mistake to deprecate it at all since it could work from the start.
"},{"location":"changelog/#096-2020-12-15","title":"0.9.6 - 2020-12-15","text":""},{"location":"changelog/#added_8","title":"Added","text":"
  • FeatureFactory can be now appended to another with plus operator.
  • DefaultOptionFactory can be now appended to another with plus operator.
"},{"location":"changelog/#changed_12","title":"Changed","text":"
  • Use description as feature flag\u2019s KDoc content.
  • Upgrade Kotlin to 1.4.21.
"},{"location":"changelog/#deprecated_3","title":"Deprecated","text":"
  • Using DeprecationLevel.Hidden is temporarily treated as an error until the compiler issue is fixed.
"},{"location":"changelog/#fixed_6","title":"Fixed","text":"
  • Make updates to the in-memory Laboratory atomic.
"},{"location":"changelog/#095-2020-12-03","title":"0.9.5 - 2020-12-03","text":""},{"location":"changelog/#added_9","title":"Added","text":"
  • Builder pattern for LaboratoryActivity.Configuration construction.
  • Visual representation of deprecated feature flags in the QA module.
  • Visual representation of deprecated feature flags can be configured via LaboratoryActivity.Configuration builder with deprecationPhenotypeSelector() and deprecationAlignmentSelector() functions.
  • Consumer ProGuard rules to laboratory-inspector to keep @Deprecated annotation.
  • QA module displays clickable hyperlinks from a feature flag description if it contains Markdown formatted links.
"},{"location":"changelog/#changed_13","title":"Changed","text":"
  • Upgrade to DataStore 1.0.0-alpha05.
"},{"location":"changelog/#deprecated_4","title":"Deprecated","text":"
  • LaboratoryActivity.Configuration() constructor. Use LaboratoryActivity.Configuration.create() or LaboratoryActivity.Configuration.builder() instead.
"},{"location":"changelog/#fixed_7","title":"Fixed","text":"
  • Warning and error level deprecation on generated feature flags is now correctly suppressed.
"},{"location":"changelog/#094-2020-11-27","title":"0.9.4 - 2020-11-27","text":""},{"location":"changelog/#added_10","title":"Added","text":"
  • Kyrie 0.2.1 to laboratory-inspector.
  • DynamicAnimation 1.0.0 to laboratory-inspector.
"},{"location":"changelog/#changed_14","title":"Changed","text":"
  • Animation of search feature in inspector. It no longer makes ugly visibility transitions.
  • Upgrade to Coroutines 1.4.2.
"},{"location":"changelog/#093-2020-11-23","title":"0.9.3 - 2020-11-23","text":""},{"location":"changelog/#added_11","title":"Added","text":"
  • Feature flags filtering to the QA module. Features are filtered by their name, options or source options.
  • ConstraintLayout 2.0.4 to laboratory-inspector.
"},{"location":"changelog/#changed_15","title":"Changed","text":"
  • Inspector tabs are now scrollable instead of fixed.
  • Upgrade to Kotlin 1.4.20.
"},{"location":"changelog/#fixed_8","title":"Fixed","text":"
  • Shared preferences based FeatureStorage dispatches now changes to feature flag observers when clear() method is used. This fixes an issue with the QA module where it did not update the UI after resetting feature flags if shared preferences where used for feature flags persistence.
  • Preserve feature flags preview adapter scroll position on configuration changes.
  • External feature factories are no longer filtered out when added with the configure() function.
"},{"location":"changelog/#092-2020-11-18","title":"0.9.2 - 2020-11-18","text":""},{"location":"changelog/#added_12","title":"Added","text":"
  • BlockingLaboratory class that can read and write feature flags via blocking API.
  • blocking() function to Laboratory class that is an entry point to the blocking API.
  • Deprecation of feature flags from the Gradle plugin with deprecated(message, level) method. level argument is optional and a warning level is used by default.
"},{"location":"changelog/#changed_16","title":"Changed","text":"
  • Upgrade to DataStore 1.0.0-alpha04.
"},{"location":"changelog/#deprecated_5","title":"Deprecated","text":"
  • All blocking functions on the Laboratory class. BlockingLaboratory available via blocking() function should be used instead.
"},{"location":"changelog/#091-2020-11-12","title":"0.9.1 - 2020-11-12","text":""},{"location":"changelog/#added_13","title":"Added","text":"
  • Builder pattern for Laboratory construction.
  • DefaultOptionFactory that can substitute default options for feature flags read by Laboratory.
  • clear() function to FeatureStorage and Laboratory.
"},{"location":"changelog/#changed_17","title":"Changed","text":"
  • Upgrade to DataStore 1.0.0-alpha03.
"},{"location":"changelog/#deprecated_6","title":"Deprecated","text":"
  • Laboratory(storage) constructor. Use Laboratory.create(storage) or Laboratory.builder() instead.
"},{"location":"changelog/#090-2020-11-11","title":"0.9.0 - 2020-11-11","text":""},{"location":"changelog/#added_14","title":"Added","text":"
  • Groovy DSL for adding feature flags via Gradle plugin. This is equivalent to feature(\"SomeFeatureFlag\") function.
    laboratory {\nSomeFeatureFlag {\nwithDefaultOption(\"Enabled\")\nwithOption(\"Disabled\")\n}\n}\n
  • options extension to Class<Feature<T>> that returns all available feature flag options.
  • defaultOption extension to Class<Feature<T>> that returns a default option of a feature flag.
  • source extension to Class<Feature<*>> that returns a feature flag source if available.
  • description extension to Class<Feature<*>> that returns a feature flag description if available.
  • withOption() and withDefaultOption() to Gradle plugin for adding options to feature flags.
  • defaultOption property to Feature interface.
  • setOption() and setOptions() functions to Laboratory and FeatureStorage.
"},{"location":"changelog/#changed_18","title":"Changed","text":"
  • excludeProjects plugin functions are now called projectFilter and the condition is reversed. Previously they removed projects that matched a condition. Now they allow projects that match it.
  • sourcedWith property on Feature is now named source.
  • Upgrade to Coroutines 1.4.1.
"},{"location":"changelog/#deprecated_7","title":"Deprecated","text":"
  • withValue() and withDefaultValue() functions in Gradle plugin. withOption() and withDefaultOption() should be used instead.
  • setFeature() and setFeatures() functions. setOption() and setOptions() should be used instead.
"},{"location":"changelog/#removed_5","title":"Removed","text":"
  • ProjectFilter from laboratory-gradle-plugin in favour of java.util.function.Predicate.
  • configure() overload which accepts sources factory as a separate argument.
  • isDefaultValue from Feature interface. defaultOption should be used instead.
"},{"location":"changelog/#fixed_9","title":"Fixed","text":"
  • Moved generateSourcedFeatureStorage task to a correct tasks group.
"},{"location":"changelog/#080-2020-10-28","title":"0.8.0 - 2020-10-28","text":""},{"location":"changelog/#added_15","title":"Added","text":"
  • KDoc documentation.
"},{"location":"changelog/#changed_19","title":"Changed","text":"
  • Renamed feature/features argument in setFeature() and setFeatures() methods to value/values respectively.
  • Elevation is no longer an attribute in the IoMehowLaboratory.Theme and a regular resource is used instead. This makes sure that when an Activity theme is overridden externally it won\u2019t crash for an unknown attribute.
  • Flatten Hyperion button to visually match other items.
  • Upgrade to Coroutines 1.4.0.
  • Upgrade to Wire 3.5.0.
"},{"location":"changelog/#removed_6","title":"Removed","text":"
  • generateFactory property from sourcedFeatureStorage() method in Gradle plugin. It was added to the public API by a mistake and wasn\u2019t responsible for anything.
  • Wire dependency from the library-shared-preferences artifact. It was added by a mistake.
  • BuildConfig classes from Android library modules.
"},{"location":"changelog/#070-2020-10-22","title":"0.7.0 - 2020-10-22","text":""},{"location":"changelog/#changed_20","title":"Changed","text":"
  • Changelog format follows now Keep a Changelog format. Format is applied retroactively to this file.
  • R8 rules are now a part of META-INF of the laboratory artifact.
  • SharedPreferencesFeatureStorage is now internal.
  • Gradle plugin no longer has a runtime dependency on Android Gradle Plugin.
  • laboratory-generator generates source code compatible with the explicit API mode.
  • Set compile SDK to 30.
  • Upgrade to KotlinPoet 1.7.2.
  • Upgrade to Hyperion 0.9.30.
  • Upgrade to DataStore 1.0.0-alpha02.
"},{"location":"changelog/#062-2020-10-12","title":"0.6.2 - 2020-10-12","text":""},{"location":"changelog/#added_16","title":"Added","text":"
  • FeatureStorage extensions for creation of SharedPreferences based FeatureStorage.
  • FeatureStorage extensions for creation of DataStore based FeatureStorage.
  • Hyperion plugin can be ordered in the debug menu by overriding io_mehow_laboratory_plugin_id resource.
"},{"location":"changelog/#deprecated_8","title":"Deprecated","text":"
  • SharedPreferenceFeatureStorage soon will become internal.
"},{"location":"changelog/#changed_21","title":"Changed","text":"
  • DataStoreFeatureStorage is now internal. It is not considered a breaking change as DataStore is in the alpha stage.
"},{"location":"changelog/#061-2020-10-12","title":"0.6.1 - 2020-10-12","text":""},{"location":"changelog/#fixed_10","title":"Fixed","text":"
  • Hyperion plugin layout where button was on the wrong side of the debug menu.
"},{"location":"changelog/#060-2020-10-12","title":"0.6.0 - 2020-10-12","text":""},{"location":"changelog/#added_17","title":"Added","text":"
  • Feature can have now description. It can be used to add more contextual data to feature flags.
  • LaboratoryActivity observes changes to feature flags instead of loading them every time the screen is opened.
  • LaboratoryActivity displays feature flag sources next to them and allows users to select a source from a drop down menu.
  • Remote feature flag values are displayed in LaboratoryActivity if a source is not local.
  • When a remote source is used for a feature flag a value cannot be changed from LaboratoryActivity.
  • LaboratoryActivity displays feature flag descriptions if they are present.
  • LaboratoryActivity can reset feature flag values to their default state from an item in the action bar.
  • Laboratory.experimentIs() and Laboratory.experimentIsBlocking() functions that allow to check if a feature flag has particular value.
  • ViewPager2 1.0.0 dependency to laboratory-inspector.
  • RecyclerView 1.1.0 dependency to laboratory-inspector.
"},{"location":"changelog/#changed_22","title":"Changed","text":"
  • LaboratoryActivity requires now a Laboratory instance for initialization. This Laboratory should share FeatureStorage with instances of Laboratory used in the application.
"},{"location":"changelog/#050-2020-10-08","title":"0.5.0 - 2020-10-08","text":""},{"location":"changelog/#changed_23","title":"Changed","text":"
  • fallback nomenclature to default. This affects Gradle plugin withFallbackValue() and withFallbackSources() functions as well as isFallbackValue property on the Feature interface.
"},{"location":"changelog/#040-2020-10-08","title":"0.4.0 - 2020-10-08","text":""},{"location":"changelog/#changed_24","title":"Changed","text":"
  • Name of the generated sourced FeatureStorage extension function is now sourcedGenerated() in order to align it with the generated feature factory extension function name.
"},{"location":"changelog/#030-2020-10-08","title":"0.3.0 - 2020-10-08","text":""},{"location":"changelog/#added_18","title":"Added","text":"
  • Feature flags can have multiple sources. Source is also a feature flag and is optional. If no source is available it is assumed that only a local source is controlled.
  • FeatureStorage that connects feature flags with their sources. It is available via FeatureStorage.sourced() extension function. Feature flag sources are uniquely identified only by their value names.
  • Feature flag sources can be set from the Gradle plugin with withSource(\"Name\") and withFallbackSource(\"Name\") functions in feature() blocks. Any source that has the name \u201cLocal\u201d (or a variant of it) is filtered out.
  • Gradle plugin has a new sourcedStorage() function. It is responsible for generating a customized FeatureStorage that is aware of all available feature flag sources.
  • Gradle plugin has a new featureSourceFactory() function. It works similarly to featureFactory() function with a difference that it collects only feature flag sources.
  • LaboratoryActivity is now configurable with the configure() function.
  • LaboratoryActivity can display different sets of feature flags on separate tabs.
  • FragmentKtx 1.2.5 dependency to laboratory-inspector.
  • ViewModelKtx 2.2.0 dependency to laboratory-inspector.
"},{"location":"changelog/#changed_25","title":"Changed","text":"
  • LaboratoryActivity.initialize() function is renamed to configure().
  • Gradle plugin factory() function is renamed to featureFactory().
"},{"location":"changelog/#021-2020-10-02","title":"0.2.1 - 2020-10-02","text":""},{"location":"changelog/#added_19","title":"Added","text":"
  • Laboratory exposes a blocking way of reading and writing feature flags. It requires an opt-in BlockingIoCall annotation.
"},{"location":"changelog/#changed_26","title":"Changed","text":"
  • laboratory-android artifact is now laboratory-shared-preferences artifact.
  • laboratory-shared-preferences artifact (old laboratory-android) is no longer automatically applied by Gradle plugin in Android modules.
  • Upgrade to Kotlin 1.4.10.
  • Upgrade to CoreKtx 1.3.2.
  • Upgrade to Wire 3.4.0.
  • Upgrade to KotlinPoet 1.6.0.
"},{"location":"changelog/#020-2020-09-05","title":"0.2.0 - 2020-09-05","text":""},{"location":"changelog/#added_20","title":"Added","text":"
  • Laboratory.observe() function to observe feature flag changes via Flow.
  • Support for DataStore with the laboratory-data-store artifact.
  • Laboratory and FeatureStorage return a boolean information whether writes are successful.
  • Feature interface that is used to define feature flags.
  • Wire 3.2.2 dependency to laboratory-data-store.
"},{"location":"changelog/#changed_27","title":"Changed","text":"
  • Kotlin standard library is now part of the public API.
  • Laboratory and FeatureStorage expose their API via suspend functions.
  • Gradle plugin requires exactly one feature flag value to be added with withFallbackValue(\"Name\") function.
  • Upgrade to Kotlin 1.4.0.
  • Upgrade to Material 1.2.1.
  • Upgrade to Hyperion 0.9.29.
"},{"location":"changelog/#removed_7","title":"Removed","text":"
  • @Feature annotation. Feature flags should implement the Feature interface.
"},{"location":"changelog/#010-2020-08-03","title":"0.1.0 - 2020-08-03","text":"
  • Initial release.
"},{"location":"gradle-plugin/","title":"Gradle plugin","text":""},{"location":"gradle-plugin/#gradle-plugin","title":"Gradle plugin","text":"

Gradle plugin\u2019s main job is to make your life easier when creating and managing feature flags. It generates features, feature factories, and customized sourced feature storage. Plugin, additionally, verifies things that cannot be represented by the API. For example, it checks if a feature flag has exactly one default option defined.

Under the hood, the Gradle plugin uses KotlinPoet to generate compact source files.

Info

The Gradle plugin automatically adds the laboratory artifact to dependencies.

Tip

The best way to understand the Gradle plugin is to check the samples. It uses most of the Gradle plugin features that most of the applications need.

"},{"location":"gradle-plugin/#feature-flags","title":"Feature flags","text":"

Feature flags are added to the generation process with a feature() function, which uses the generateFeatureFlags Gradle task. Here is a sample configuration.

Tip

Check the sample with demo configuration.

apply plugin: \"io.mehow.laboratory\"\n\nlaboratory {\npackageName = \"io.mehow.laboratory.sample\"\n\nfeature(\"Authentication\") {\ndescription = \"Type of authentication when opening the app\"\n\nwithOption(\"None\")\nwithOption(\"Fingerprint\")\nwithDefaultOption(\"Retina\")\n}\n\nfeature(\"LocationTracking\") {\npackageName = \"io.mehow.laboratory.location\"\n\nisPublic = false\n\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n\nwithDefaultSource(\"Firebase\")\nwithSource(\"Aws\")\n}\n}\n

This setup creates two feature flags. Authentication and LocationTracking with options taken from the feature(name) { } block. Key things that might not be that obvious.

  • Feature flag source visibility is inherited from a feature\u2019s visibility.
  • If a feature flag defines a remote source, a Local source is automatically added as an option. Any custom Local sources will be filtered out.
  • If all sources are added with withSource() function, Local source will be used as a default one.
package io.mehow.laboratory.sample\n\nimport io.mehow.laboratory.Feature\nimport kotlin.Boolean\nimport kotlin.String\n\npublic enum class Authentication : Feature<Authentication> {\nPassword,\nFingerprint,\nRetina,\n;\n\npublic override val defaultOption get() = Retina\n\npublic override val description: String = \"Type of authentication when opening the app\"\n}\n
package io.mehow.laboratory.location\n\nimport io.mehow.laboratory.Feature\nimport java.lang.Class\nimport kotlin.Boolean\nimport kotlin.Suppress\n\ninternal enum class LocationTracking : LocationTracking<Authentication> {\nEnabled,\nDisabled,\n;\n\npublic override val defaultOption get() = Disabled\n\npublic override val source = Source::class.java\n\ninternal enum class Source : Feature<Source> {\nLocal,\nFirebase,\nAws,\n;\n\npublic override val defaultOption get() = Firebase\n}\n}\n
"},{"location":"gradle-plugin/#supervision","title":"Supervision","text":"

Gradle plugin supports generation of supervised feature flags.

Tip

Check the sample with demo configuration.

laboratory {\nfeature(\"ChristmasTheme\") {\nwithDefaultOption(\"Disabled\")\n\nwithOption(\"Enabled\") { enabledChristmas ->\nenabledChristmas.feature(\"Greeting\") { greeting ->\ngreeting.withDefaultOption(\"Hello\")\ngreeting.withOption(\"HoHoHo\")\n}\n\nenabledChristmas.feature(\"Background\") { background ->\nbackground.withDefaultOption(\"White\")\nbackground.withOption(\"Reindeer\")\nbackground.withOption(\"Snowman\")\n}\n}\n}\n}\n

This configuration generates the code below.

enum class ChristmasTheme : Feature<ChristmasTheme> {\nEnabled,\nDisabled,\n;\n\npublic override val defaultOption get() = Disabled\n}\n\nenum class Greeting : Feature<Greeting> {\nHello,\nHoHoHo,\n;\n\npublic override val defaultOption get() = Hello\n\npublic override val supervisorOption get() = ChristmasTheme.Enabled\n}\n\nenum class Background : Feature<Background> {\nWhite,\nReindeer,\nSnowman,\n;\n\npublic override val defaultOption get() = White\n\npublic override val supervisorOption get() = ChristmasTheme.Enabled\n}\n

DSL for supervised feature flags is recursive allowing to nest them in withOption() and withDefaultOption() functions.

"},{"location":"gradle-plugin/#feature-flags-storage","title":"Feature flags storage","text":"

If your feature flags use multiple sources, you can configure the Gradle plugin to generate for you a quality of life extension function that returns a custom FeatureStorage builder.

apply plugin: \"io.mehow.laboratory\"\n\nlaboratory {\npackageName = \"io.mehow.laboratory.sample\"\n\nsourcedStorage()\n\nfeature(\"FeatureA\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n\nwithSource(\"Azure\")\nwithSource(\"Firebase\")\n}\n\nfeature(\"FeatureB\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n\nwithSource(\"Azure\")\nwithSource(\"Aws\")\n}\n\nfeature(\"FeatureC\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n\nwithSource(\"Heroku\")\n}\n\nfeature(\"FeatureD\") {\nwithDefaultOption(\"Enabled\")\nwithOption(\"Disabled\")\n}\n}\n

sourcedBuilder() function uses generateSourcedFeatureStorage Gradle task that generates the code below.

package io.mehow.laboratory.sample\n\nimport io.mehow.laboratory.FeatureStorage\nimport io.mehow.laboratory.FeatureStorage.Companion.sourced\nimport kotlin.String\nimport kotlin.collections.Map\nimport kotlin.collections.emptyMap\nimport kotlin.collections.plus\nimport kotlin.to\n\ninternal fun FeatureStorage.Companion.sourcedBuilder(localSource: FeatureStorage): AwsStep =\nBuilder(localSource, emptyMap())\n\ninternal interface AwsStep {\npublic fun awsSource(source: FeatureStorage): AzureStep\n}\n\ninternal interface AzureStep {\npublic fun azureSource(source: FeatureStorage): FirebaseStep\n}\n\ninternal interface FirebaseStep {\npublic fun firebaseSource(source: FeatureStorage): HerokuStep\n}\n\ninternal interface HerokuStep {\npublic fun herokuSource(source: FeatureStorage): BuildingStep\n}\n\ninternal interface BuildingStep {\npublic fun build(): FeatureStorage\n}\n\nprivate data class Builder(\nprivate val localSource: FeatureStorage,\nprivate val remoteSources: Map<String, FeatureStorage>\n) : AwsStep, AzureStep, FirebaseStep, HerokuStep, BuildingStep {\npublic override fun awsSourceSource(source: FeatureStorage): AzureStep = copy(\nremoteSources = remoteSources + (\"Firebase\" to source)\n)\n\npublic override fun azureSource(source: FeatureStorage): FirebaseStep = copy(\nremoteSources = remoteSources + (\"Azure\" to source)\n)\n\npublic override fun firebaseSource(source: FeatureStorage): HerokuStep = copy(\nremoteSources = remoteSources + (\"Firebase\" to source)\n)\n\npublic override fun herokuSource(source: FeatureStorage): BuildingStep = copy(\nremoteSources = remoteSources + (\"Heroku\" to source)\n)\n\npublic override fun build(): FeatureStorage = sourced(localSource, remoteSources)\n}\n
"},{"location":"gradle-plugin/#feature-flags-factory","title":"Feature flags factory","text":"

The generation of feature flags factory is useful if you use the QA module.

Tip

Check the samples with demo configurations.

apply plugin: \"io.mehow.laboratory\"\n\nlaboratory {\npackageName = \"io.mehow.laboratory.sample\"\n\nfeatureFactory()\n\nfeature(\"FeatureA\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n\nfeature(\"FeatureB\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n\nfeature(\"FeatureC\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n}\n

featureFactory() uses generateFeatureFactory Gradle task that generates the code below. Class.forname() is used for lookup instead of the direct reference to classes because there is no guarantee that feature flags are directly available in the module that generates the factory if feature flags come, for example, as transitive dependencies of other modules.

package io.mehow.laboratory.sample\n\nimport io.mehow.laboratory.Feature\nimport io.mehow.laboratory.FeatureFactory\nimport java.lang.Class\nimport kotlin.Suppress\nimport kotlin.collections.Set\nimport kotlin.collections.setOf\n\ninternal fun FeatureFactory.Companion.featureGenerated(): FeatureFactory = GeneratedFeatureFactory\n\nprivate object GeneratedFeatureFactory : FeatureFactory {\n@Suppress(\"UNCHECKED_CAST\")\noverride fun create(): Set<Class<out Feature<*>>> = setOf(\nClass.forName(\"io.mehow.laboratory.sample.FeatureA\"),\nClass.forName(\"io.mehow.laboratory.sample.FeatureB\"),\nClass.forName(\"io.mehow.laboratory.sample.FeatureC\")\n) as Set<Class<Feature<*>>>\n}\n
"},{"location":"gradle-plugin/#feature-flag-sources-factory","title":"Feature flag sources factory","text":"

If you want to group all feature flag sources similar to feature flags, you can use featureSourceFactory() function that collects them.

laboratory {\npackageName = \"io.mehow.laboratory.sample\"\n\nfeatureSourceFactory()\n\nfeature(\"FeatureA\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n\nwithSource(Remote)\n}\n\nfeature(\"FeatureB\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n\nwithSource(Remote)\n}\n}\n

This uses the generateFeatureSourceFactory Gradle task that generates the code below.

package io.mehow.laboratory.sample\n\nimport io.mehow.laboratory.Feature\nimport io.mehow.laboratory.FeatureFactory\nimport java.lang.Class\nimport kotlin.Suppress\nimport kotlin.collections.Set\nimport kotlin.collections.setOf\n\ninternal fun FeatureFactory.Companion.featureSourceGenerated(): FeatureFactory =\nGeneratedFeatureSourceFactory\n\nprivate object GeneratedFeatureSourceFactory : FeatureFactory {\n@Suppress(\"UNCHECKED_CAST\")\noverride fun create(): Set<Class<out Feature<*>>> = setOf(\nClass.forName(\"io.mehow.laboratory.sample.FeatureA${'$'}Source\"),\nClass.forName(\"io.mehow.laboratory.sample.FeatureB${'$'}Source\")\n) as Set<Class<Feature<*>>>\n}\n
"},{"location":"gradle-plugin/#feature-flag-option-factory","title":"Feature flag option factory","text":"

The generation of an option factory is useful when you want to control local feature flag options remotely. Option factory aggregates all feature flags and recognizes them either by a fully qualified class name or an optional key property on a feature flag. Keys must be unique and cannot match fully qualified class names of other feature flags.

apply plugin: \"io.mehow.laboratory\"\n\nlaboratory {\npackageName = \"io.mehow.laboratory.sample\"\n\noptionFactory()\n\nfeature(\"FeatureA\") {\nkey = \"FeatureA\"\n\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n\nfeature(\"FeatureB\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n\nfeature(\"FeatureC\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n}\n

This uses the generateOptionFactory Gradle task that generates the code below.

package io.mehow.laboratory.sample\n\nimport io.mehow.laboratory.Feature\nimport io.mehow.laboratory.OptionFactory\n\ninternal fun OptionFactory.Companion.generated(): OptionFactory = GeneratedOptionFactory\n\nprivate object GeneratedOptionFactory : OptionFactory {\noverride fun create(key: String, name: String): Feature<*>? = when (key) {\n\"FeatureA\" -> when (name) {\n\"Enabled\" -> FeatureA.Enabled\n\"Disabled\" -> FeatureA.Disabled\nelse -> null\n}\n\"io.mehow.laboratory.sample.FeatureB\" -> when (name) {\n\"Enabled\" -> FeatureB.Enabled\n\"Disabled\" -> FeatureB.Disabled\nelse -> null\n}\n\"io.mehow.laboratory.sample.FeatureC\" -> when (name) {\n\"Enabled\" -> FeatureC.Enabled\n\"Disabled\" -> FeatureC.Disabled\nelse -> null\n}\nelse -> null\n}\n}\n
"},{"location":"gradle-plugin/#multi-module-support","title":"Multi-module support","text":"

The Gradle plugin was written with support for multi-module projects in mind.

Tip

Check the sample with demo configuration.

.\n\u251c\u2500 module-a\n\u2502  \u2514\u2500 build.gradle\n\u251c\u2500 module-b\n\u2502  \u2514\u2500 build.gradle\n\u251c\u2500 module-app\n\u2502  \u2514\u2500 build.gradle\n\u251c\u2500 build.gradle\n\u2514\u2500 settings.gradle\n

A Laboratory setup for a Gradle project like above could look like this. Configuration of the Android Gradle plugin or any other dependencies is omitted for brevity.

// module-a\nplugins {\nid \"org.jetbrains.kotlin.jvm\"\nid \"io.mehow.laboratory\"\n}\n\nlaboratory {\npackageName = \"com.sample.a\"\n\nfeature(\"Authentication\") {\nwithDefaultOption(\"Password\")\nwithOption(\"Fingerprint\")\nwithOption(\"Retina\")\nwithOption(\"Face\")\n\nwithSource(\"Firebase\")\nwithSource(\"Aws\")\n}\n\nfeature(\"AllowScreenshots\") {\nwithOption(\"Enabled\")\nwithDefaultOption(\"Disabled\")\n}\n}\n
// module-b\nplugins {\nid \"org.jetbrains.kotlin.jvm\"\nid \"io.mehow.laboratory\"\n}\n\nlaboratory {\npackageName = \"com.sample.b\"\n\nfeature(\"DistanceAlgorithm\") {\nisPublic = false\n\nwithDefaultOption(\"Euclidean\")\nwithOption(\"Jaccard\")\nwithOption(\"Cosine\")\nwithOption(\"Edit\")\nwithOption(\"Hamming\")\n\nwithSource(\"Firebase\")\nwithDefaultSource(\"Azure\")\n}\n}\n\ndependencies {\nimplementation project(\":module-a\")\n}\n
// module-app\nplugins {\nid \"com.android.application\"\nid \"org.jetbrains.kotlin.android\"\nid \"io.mehow.laboratory\"\n}\n\nlaboratory {\npackageName = \"com.sample\"\nsourcedStorage()\nfeatureFactory()\n\ndependency(project(\":module-a\"))\ndependency(project(\":module-b\"))\n}\n\ndependencies {\nimplementation project(\":module-b\")\n}\n

This setup shows that each module can define its feature flags that do not have to be exposed outside. In this scenario, module-app is responsible only for gluing together all feature flags so that Laboratory instances are aware of feature flag sources and the QA module. It should then deliver the correct Laboratory to modules via dependency injection. In order to include feature flags during generation of factories, their modules need to be added with dependency function.

"},{"location":"gradle-plugin/#full-configuration","title":"Full configuration","text":"

Below is the full configuration of the Gradle plugins.

laboratory {\n// Sets namespace of generated features and factories. Empty by default.\npackageName = \"io.mehow.sample\"\n\n// Informs plugin to create 'enum class SomeFeature' during the generation period.\nfeature(\"SomeFeature\") {\n// Used for option factory lookup. No value by default.\nkey = \"SomeFeatureKey\"\n\n// Overrides globally declared namespace. No value by default.\npackageName = \"io.mehow.sample.feature\"\n\n// Adds a description to this feature that can be used for more context.\ndescription = \"Feature description\"\n\n// Sets the visibility of a feature flag to be either 'public' or 'internal'. 'true' by default.\nisPublic = false\n\n// Deprecates a feature flag. `DeprecationLevel` argument is optional and uses `DeprecationLevel.Warning` by default.\n// Add the class to the import list in your Gradle script to avoid typing the whole package name.\ndeprecated(\"Deprecation message\", io.mehow.laboratory.gradle.DeprecationLevel.Hidden)\n\n// Informs plugin to add 'ValueA' option to the generated feature flag and set it as a default option.\n// Exactly one of the feature options must be set with this function.\nwithDefaultOption(\"ValueA\")\n\n// Informs plugin to add 'ValueB' option to the generated feature flag.\nwithOption(\"ValueB\")\n\n// Informs plugin to add 'Firebase' option to the list of sources controlling this flag.\n// Adding any source automatically adds the 'Local' option to the source enum.\n// Any custom 'Local' sources are ignored by the plugin.\nwithSource(\"Firebase\")\n\n// Informs plugin to add 'Aws' option to the list of sources controlling this flag and to set a default option.\n// At most, one of the source options can be set with this function.\n// By default, 'Local' sources are considered to be default options.\nwithDefaultSource(\"Aws\")\n\n// Same as `withDefaultOption(option)` without lambda except that it generates supervised feature flags\n// defined in the lambda.\nwithDefaultOption(\"Option\") { option ->\noption.feature(\"SupervisedFeature\") {\n// recursive feature generation\n}\n}\n\n// Same as `withOption(option)` without lambda except that it generates supervised feature flags\n// defined in the lambda.\nwithOption(\"Option\") { option ->\noption.feature(\"SupervisedFeature\") {\n// recursive feature generation\n}\n}\n}\n\n// Informs plugin to create 'enum class SomeFeature' during the generation period with two options.\n// 'Enabled' and 'Disabled' and uses 'Enabled' as the default one.\nenabledFeature(\"SomeFeature\") {\n// Uses the same options as feature() block except for `withOption()` and `withDefaultOption()`.\n\nwithEnabled { option ->\noption.feature(\"SupervisedFeature\") {\n// recursive feature generation\n}\n}\n}\n\n// Informs plugin to create 'enum class SomeFeature' during the generation period with two options.\n// 'Enabled' and 'Disabled' and uses 'Disabled' as the default one.\ndisabled(\"SomeFeature\") {\n// Uses the same options as feature() block except for `withOption()` and `withDefaultOption()`.\n\nwithEnabled { option ->\noption.feature(\"SupervisedFeature\") {\n// recursive feature generation\n}\n}\n}\n\n// Configures feature flags storage. Useful when feature flags have multiple sources.\nsourcedStorage {\n// Overrides globally declared namespace. No value by default.\npackageName = \"io.mehow.sample.storage\"\n\n// Sets visibility of a storage extension function to be either 'public' or 'internal'. 'false' by default.\nisPublic = true\n}\n\n// Configures option factory. Useful for integration with remote service such as Firebase.\noptionFactory {\n// Overrides globally declared namespace. No value by default.\npackageName = \"io.mehow.sample.factory\"\n\n// Sets visibility of a factory extension function to be either 'public' or 'internal'. 'false' by default.\nisPublic = true\n}\n\n// Configures feature flags factory. Useful for the QA module configuration.\nfeatureFactory {\n// Overrides globally declared namespace. No value by default.\npackageName = \"io.mehow.sample.factory\"\n\n// Sets visibility of a factory extension function to be either 'public' or 'internal'. 'false' by default.\nisPublic = true\n}\n\n// Configures feature flag sources factory.\nfeatureSourceFactory {\n// Overrides globally declared namespace. No value by default.\npackageName = \"io.mehow.sample.factory\"\n\n// Sets visibility of a factory extension function to be either 'public' or 'internal'. 'false' by default.\nisPublic = true\n}\n\n// Includes feature flags that are used for generation of feature factories, sourced storage and option factory.\ndependency(project(\":some-project\"))\n// By default dependency contributes to all declared generators but it can be selectively applied\n// by passing a contribution list.\ndependency(project(\":some-project\"), [DependencyContribution.FeatureFactory, DependencyContribution.OptionFactory])\n// If typesafe project accessors are enabled.\ndependency(projects.someProject)\n}\n
"},{"location":"qa-module/","title":"QA module","text":""},{"location":"qa-module/#qa-module","title":"QA module","text":"

It is very often desirable to have the option of configuring feature flag options at runtime. Laboratory addresses this problem with its QA modules.

"},{"location":"qa-module/#inspector","title":"Inspector","text":"

Feature flags inspection is available through the laboratory-inspector artifact. LaboratoryActivity is an Activity that enables inspection and modifications of feature flags.

Inspector displays feature flags as cards and their options on chips. Active options of feature flags are marked with a highlight color. A local option of a feature flag can be changed by tapping on a chip. Chips that do not use Local sources cannot have their options changed. If a feature flag has multiple sources available, they can be switched from a drop down menu.

Feature flags (including sources) can be reset to their default options with a button in an action bar.

"},{"location":"qa-module/#configuration","title":"Configuration","text":"

Before LaboratoryActivity can be started, it has to be configured with an instance of Laboratory and at least one instance of FeatureFactory. FeatureFactory is an interface that should gather feature flags that are logically grouped together. Logical grouping can be different for each application, but in most cases, all feature flags in the project belong to a single unit. Scenarios, when you might want to split feature flags, are for example:

  • Feature flags that do not belong to your project and are exposed to you from an external library.
  • Abundance of feature flags and a need to increase the readability of the inspector interface by separating feature flags into custom categories.

Tip

A lot of the boilerplate code presented here can be generated with the Gradle plugin. It is highly recommended to rely on the plugin instead of handwriting the code.

val sourcedFeatureStorage = FeatureStorage.sourced(\nlocalSource = FeatureStorage.inMemory(),\nremoteSources = mapOf(\n\"Firebase\" to FeatureStorage.inMemory(),\n\"Aws\" to FeatureStorage.inMemory(),\n\"Azure\" to FeatureStorage.inMemory(),\n),\n)\nval laboratory = Laboratory.create(sourcedFeatureStorage)\n\nLaboratoryActivity.configure(\nlaboratory = laboratory,\nfeatureFactory = CustomFeatureFactory,\n)\nLaboratoryActivity.start(context)\n\nobject CustomFeatureFactory : FeatureFactory {\noverride fun create(): Set<Class<out Feature<*>>> = setOf(\nAllowScreenshots::class.java,\nAuthentication::class.java,\nPowerSource::class.java,\nDistanceAlgorithm::class.java,\nLogType::class.java,\n)\n}\n\nenum class AllowScreenshots : Feature<AllowScreenshots> {\nEnabled,\nDisabled;\n\npublic override val defaultOption get() = Disabled\n\noverride val description: String = \"Enables or disables screenshots during a video chat\"\n}\n\nenum class Authentication : Feature<Authentication> {\nPassword,\nFingerprint,\nRetina,\nFace;\n\npublic override val defaultOption get() = Password\n\noverride val source = Source::class.java\n\nenum class Source : Feature<Source> {\nLocal,\nFirebase,\nAws;\n\npublic override val defaultOption get() = Local\n}\n}\n\nenum class DistanceAlgorithm : Feature<DistanceAlgorithm> {\nEuclidean,\nJaccard,\nCosine,\nEdit,\nHamming;\n\npublic override val defaultOption get() = Euclidean\n\n@Suppress(\"UNCHECKED_CAST\")\noverride val source: Class<Feature<*>> = Source::class.java as Class<Feature<*>>\n\noverride val description: String = \"Algorithm used for destination distance calculations\"\n\nenum class Source : Feature<Source> {\nLocal,\nFirebase,\nAzure;\n\npublic override val defaultOption get() = Azure\n}\n}\n\nenum class LogType : Feature<LogType> {\nVerbose,\nDebug,\nInfo,\nWarning,\nError;\n\npublic override val defaultOption get() = Info\n}\n\nenum class PowerSource : Feature<PowerSource> {\nCoal,\nWind,\nSolar,\nNuclear,\nColdFusion;\n\npublic override val defaultOption get() = Solar\n\n@Suppress(\"UNCHECKED_CAST\")\noverride val source: Class<Feature<*>> = Source::class.java as Class<Feature<*>>\n\nenum class Source : Feature<Source> {\nLocal,\nFirebase;\n\npublic override val defaultOption get() = Firebase\n}\n}\n
"},{"location":"qa-module/#deprecation","title":"Deprecation","text":"

You can configure how deprecated feature flags will be represented in the QA module. To do this you need to pass additional parameters to the Configuration builder.

val configuration = LaboratoryActivity.Configuration.builder()\n.laboratory(laboratory)\n.featureFactories(mapOf(\"Features\" to featureFactory))\n.deprecationPhenotypeSelector { deprecationLevel -> DeprecationPhenotype.Strikethrough }\n.deprecationAlignmentSelector { deprecationLevel -> DeprecationAlignment.Bottom }\n.build()\nLaboratoryActivity.configure(configuration)\n
"},{"location":"qa-module/#hyperion","title":"Hyperion","text":"

If you use Hyperion you can easily integrate Laboratory by adding the laboratory-hyperion-plugin artifact to your dependencies. This will put an item in Hyperion\u2019s debug menu.

If you\u2019d like to position the Laboratory menu item in a different place on the menu, you can override the string id resource.

<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n<string name=\"io_mehow_laboratory_plugin_id\" translatable=\"false\">!Laboratory</string>\n</resources>\n
"},{"location":"releasing/","title":"Releasing","text":""},{"location":"releasing/#releasing","title":"Releasing","text":""},{"location":"releasing/#versioning","title":"Versioning","text":"
  1. Run the prepare release script and bump the desirable version part.
  2. If there are no errors git push && git push --tags.
  3. Wait for the CI server to upload the artifacts.
  4. Visit Sonatype Nexus and promote the artifacts.
"},{"location":"releasing/#documentation-updates","title":"Documentation updates","text":"

Website documentation lives under /docs directory and is deployed with MkDocs using Material Theme. A new site is built and published for the latest commits on the trunk branch.

If you want to test the website locally before pushing changes, you need to follow these steps.

Make sure you have Python 3 and pip installed.

$ python --version\nPython 3.8.5\n\n$ pip --version\npip 20.2.4\n

Install MkDocs, Material Theme and MkDocs Video.

$ pip install mkdocs mkdocs-material mkdocs-video\n$ mkdocs --version\nmkdocs, version 1.1.2\n

Navigate to the library directory and run the site locally.

$ mkdocs serve\nINFO    -  Building documentation...\nINFO    -  Cleaning site directory\nINFO    -  Documentation built in 0.73 seconds\n[I 201026 22:51:56 server:335] Serving on http://127.0.0.1:8000\nINFO    -  Serving on http://127.0.0.1:8000\n
"},{"location":"user-guide/","title":"User guide","text":""},{"location":"user-guide/#user-guide","title":"User guide","text":""},{"location":"user-guide/#features","title":"Features","text":"

Feature flags are nothing more than enums that implement the Feature interface. It allows us to define a default option, remote sources that can provide different options and descriptions for some human-readable metadata.

Danger

Feature enums must have at least one option. Defining an enum like below will make Laboratory throw an exception when used to read an option.

enum class SomeFeature : Feature<SomeFeature>\n

Tip

Check the samples to learn by example.

"},{"location":"user-guide/#io","title":"I/O","text":"

Laboratory is nothing more than a high-level API over the FeatureStorage interface responsible for persisting feature flags. All implementations that are provided by this library rely on a feature flag package name and an enum name.

Warning

Because the persistence mechanism relies on package names and enum names, you should be careful when refactoring feature flags already available on production. Changing these options may result in a perception of unsaved feature flags.

Because FeatureStorage is an interface that is meant to be used with I/O operations, it exposes only suspend functions. Laboratory, on the other hand, allows you to opt-into blocking equivalents of read and write functions. You can selectively do this by applying the @BlockingIoCall annotation or globally by adding a compiler flag.

android {\nkotlinOptions {\nfreeCompilerArgs += [\n\"-Xopt-in=io.mehow.laboratory.BlockingIoCall\",\n]\n}\n}\n

In either case, a design that relies on non-blocking function calls is preferable.

"},{"location":"user-guide/#sources","title":"Sources","text":"

Feature flags, by default, have only a single source for their options. By convention, it is considered to be a local source. However, you might need to have different data sources for feature flags, depending on some runtime conditions or a build variant. For example, you might want to use a local source during debugging and rely on some remote services on production.

Let\u2019s say that you want to have a feature flag that has three sources. One local, and two remote ones.

Info

Notice that a feature flag source is also a feature flag. This allows us to change feature flag sources via Laboratory as well.

enum class PowerType : Feature<PowerType> {\nCoal,\nWind,\nSolar;\n\npublic override val defaultOption get() = Solar\n\n@Suppress(\"UNCHECKED_CAST\")\noverride val source = Source::class.java as Class<Feature<*>>\n\nenum class Source : Feature<Source> {\nLocal,\nFirebase,\nAzure;\n\npublic override val defaultOption get() = Firebase\n}\n}\n

If you define multiple sources for a feature flag, you should add a Local option to them. This allows changing feature flag options at runtime from the QA module.

This feature flag definition allows configuring Laboratory in a way that it is capable of recognizing that PowerType has different option providers and that the default provider is Firebase.

Because the Laboratory only delegates its work to FeatureStorage, it is FeatureStorage that needs to understand how to connect feature flags with their sources. This is possible with a special implementation of this interface that is available as an extension function.

val sourcedFeatureStorage = FeatureStorage.sourced(\nlocalSource = FeatureStorage.inMemory(),\nremoteSources = mapOf(\n\"Firebase\" to FeatureStorage.inMemory(),\n\"Azure\" to FeatureStorage.inMemory(),\n),\n)\n

sourcedFeatureStorage delegates persistence mechanism to three different storage and is responsible for coordinating a selected source and a current feature flag option.

One error-prone thing is that sourcedFeatureStorage relies on strings and source names to use the correct storage. The reason for this is that two different feature flags might share sources partially.

Tip

Using Gradle plugin allows you to avoid this issue with the generation of a custom FeatureStorage that is always up-to-date.

enum class PowerType : Feature<PowerType> {\nCoal,\nWind,\nSolar;\n\npublic override val defaultOption get() = Solar\n\n@Suppress(\"UNCHECKED_CAST\")\noverride val source = Source::class.java as Class<Feature<*>>\n\nenum class Source : Feature<Source> {\nLocal,\nFirebase,\nAzure;\n\npublic override val defaultOption get() = Firebase\n}\n}\n\nenum class Theme : Feature<PowerType> {\nNight,\nDay,\nChristmas;\n\npublic override val defaultOption get() = Night\n\n@Suppress(\"UNCHECKED_CAST\")\noverride val source = Source::class.java as Class<Feature<*>>\n\nenum class Source : Feature<Source> {\nLocal,\nAzure;\n\npublic override val defaultOption get() = Local\n}\n}\n

In this case, Theme and PowerType feature flags share Azure source, but Firebase applies only to the PowerType flag.

// Create laboratory that understands sourced features\nval laboratory = Laboratory.create(sourcedFeatureStorage)\n\n// Check option of PowerType in Firebase FeatureStorage\nval powerTypeFirebaseValue = laboratory.experiment<PowerType>()\n\n// Check option of Theme in local FeatureStorage\nval themeLocalValue = laboratory.experiment<Theme>()\n\n// Set source of Theme source to Azure (PowerType is still unaffected and uses Firebase)\nval success = laboratory.setOption(Theme.Source.Azure)\n\n// Check option of Theme in Azure FeatureStorage\nval themeAzureValue = laboratory.experiment<Theme>()\n

Info

The implementation of sourcedFeatureStorage provided by the library saves data only in localSource.

To propagate remote feature flag options on updates, they need to be connected to a remote source.

enum class ShowAds : Feature<ShowAds> {\nEnabled,\nDisabled;\n\npublic override val defaultOption get() = Disabled\n\n@Suppress(\"UNCHECKED_CAST\")\noverride val source = Source::class.java as Class<Feature<*>>\n\nenum class Source : Feature<Source> {\nLocal,\nRemote;\n\npublic override val defaultOption get() = Remote\n}\n}\n\nval firebaseStorage = FeatureStorage.inMemory()\nval sourcedFeatureStorage = FeatureStorage.sourced(\nlocalSource = FeatureStorage.inMemory(),\nremoteSources = mapOf(\"Remote\" to firebaseStorage),\n)\n\n// During application initialisation\nval laboratory = Laboratory.create(sourcedFeatureStorage)\nremoteService.observeShowAdsFlag()\n// Some custom mapping between a service option and a feature flag\n.map { showAds: Boolean ->\nval showAdsFlag = if (showAds) ShowAds.Enabled else ShowAds.Disabled\nlaboratory.setOption(showAdsFlag)\n}\n// Scope should last for the lifetime of an application\n.launchIn(GlobalScope)\n
"},{"location":"user-guide/#default-options-override","title":"Default options override","text":"

Whenever Laboratory reads an option for a feature flag, it falls back to a default option declared on a said flag. However, there might be cases when you\u2019d like to change the default behavior. One example might be having features enabled by default in your debug builds and disabled on production. Or you might use feature flags for configuration, and you\u2019d like to have a different configuration per build variant. Laboratory enables this with default options overrides.

enum class ShowAds : Feature<ShowAds> {\nEnabled,\nDisabled;\n\npublic override val defaultOption get() = Disabled\n}\n\nobject DebugDefaultOptionFactory : DefaultOptionFactory {\noverride fun <T : Feature<T>> create(feature: T): Feature<*>? = when(feature) {\nis ShowAds -> ShowAds.Enabled\nelse -> null\n}\n}\n\nval laboratory = Laboratory.builder()\n.featureStorage(FeatureStorage.inMemory())\n.defaultOptionFactory(DebugDefaultOptionFactory)\n.build()\n\n// Uses default option declared in DebugDefaultOptionFactory\nlaboratory.experimentIs(ShowAds.Enabled)\n

You can be even more creative and, for example, enable all feature flags in your debug builds, which have an option Enabled.

class DebugDefaultOptionFactory : DefaultOptionFactory {\noverride fun <T : Feature<T>> create(feature: T): Feature<*>? {\nreturn feature.options.associateBy { it.name }[\"Enabled\"]\n}\n\nprivate val <T : Feature<T>> T.options get() = javaClass.options\n}\n
"},{"location":"user-guide/#feature-flag-supervision","title":"Feature flag supervision","text":"

Feature flags can be supervised using FeatureFlag.supervisorOption property. Whenever supervisor has its option different from the value in this property then the supervised feature flag cannot return any other option than a default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised. This relationship is recursive meaning that grandparents control grandchildren indirectly.

enum class ChristmasTheme : Feature<ChristmasTheme> {\nEnabled,\nDisabled,\n;\n\npublic override val defaultOption get() = Disabled\n}\n\nenum class Greeting : Feature<Greeting> {\nHello,\nHoHoHo,\n;\n\npublic override val defaultOption get() = Hello\n\npublic override val supervisorOption get() = ChristmasTheme.Enabled\n}\n\nenum class Background : Feature<Background> {\nWhite,\nReindeer,\nSnowman,\n;\n\npublic override val defaultOption get() = White\n\npublic override val supervisorOption get() = ChristmasTheme.Enabled\n}\n\nval laboratory = Laboratory.inMemory()\n\nlaboratory.setOptions(Greeting.HoHoHo, Background.Reindeer)\n\nlaboratory.experimentIs(Greeting.HoHoHo) // false\nlaboratory.experimentIs(Background.Reindeer) // false\n\nlaboratory.setOption(ChristmasTheme.Enabled)\n\nlaboratory.experimentIs(Greeting.HoHoHo) // true\nlaboratory.experimentIs(Background.Reindeer) // true\n
"},{"location":"user-guide/#listening-to-remote-change","title":"Listening to remote change","text":"

Feature flags can be synced with a remote source with a help of OptionFactory. Below is a sample setup using Firebase.

enum class ChristmasTheme : Feature<ChristmasTheme> {\nEnabled,\nDisabled,\n;\n\npublic val override val defaultOption get() = Disabled\n}\n\nenum class ShowAds : Feature<ShowAds> {\nEnabled,\nDisabled;\n\npublic override val defaultOption get() = Disabled\n}\n\nobject CustomOptionFactory : OptionFactory {\nprivate val optionMapping = mapOf<String, (String) -> Feature<*>?>(\n\"ChristmasTheme\" to { name -> ChristmasTheme::class.java.options.firstOrNull { it.name == name } },\n\"ShowAds\" to { name -> ShowAds::class.java.options.firstOrNull { it.name == name } },\n)\n\noverride fun create(key: String, name: String) = optionMapping[key]?.invoke(name)\n}\n\nclass App : Application {\noverride fun onCreate() {\nval firebaseStorage = FeatureStorage.inMemory()\n// Get a reference to a node where feature flags are kept\nval database = FirebaseDatabase.getInstance().reference.child(\"featureFlags\")\n\nval featureFlagListener = object : ValueEventListener {\noverride fun onDataChange(snapshot: DataSnapshot) {\nval newOptions = (snapshot.value as? Map<*, *>)\n.orEmpty()\n.mapNotNull { (key, value) ->\nval stringKey = key as? String ?: return@mapNotNull null\nval stringValue = value as? String ?: return@mapNotNull null\nCustomOptionFactory.create(stringKey, stringValue)\n}\n// Be cautious with using GlobalScope.\nGlobalScope.launch { firebaseStorage.setOptions(newOptions) }\n}\n\noverride fun onCancelled(error: DatabaseError) = Unit\n}\n\ndatabase.child(\"featureFlags\").addValueEventListener(featureFlagListener)\n}\n}\n
"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 000000000..b61fa0d6a --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,33 @@ + + + + https://mehow.io/laboratory/ + 2024-12-02 + daily + + + https://mehow.io/laboratory/changelog/ + 2024-12-02 + daily + + + https://mehow.io/laboratory/gradle-plugin/ + 2024-12-02 + daily + + + https://mehow.io/laboratory/qa-module/ + 2024-12-02 + daily + + + https://mehow.io/laboratory/releasing/ + 2024-12-02 + daily + + + https://mehow.io/laboratory/user-guide/ + 2024-12-02 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..f87899315da997efd9f43662d7a9da813ed54f07 GIT binary patch literal 257 zcmV+c0sj6UiwFp3VohfP|8r?{Wo=<_E_iKh0L_y@Zo?oDMfW*{#U947x@aq#>~ezU z0Mtw|5(bBXI=Ovu997uUC&w^~iQB5R5G(i1OHUv)*YVpS8p(?cmtgA=0F7$Fqp%OFV z5N2TmIQ1E#N+I5%g~hQwpeT(&%cgE#__5)2Q!GzyW9tXy4Sq$uO0BHBx3E!G68J^= zE7Th0g4rjYiAp=c#7cd- literal 0 HcmV?d00001 diff --git a/user-guide/index.html b/user-guide/index.html new file mode 100644 index 000000000..c5d8444bd --- /dev/null +++ b/user-guide/index.html @@ -0,0 +1,819 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + User guide - Laboratory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + +

User guide

+

Features

+

Feature flags are nothing more than enums that implement the Feature interface. It allows us to define a default option, remote sources that can provide different options and descriptions for some human-readable metadata.

+
+

Danger

+

Feature enums must have at least one option. Defining an enum like below will make Laboratory throw an exception when used to read an option.

+
+
enum class SomeFeature : Feature<SomeFeature>
+
+
+

Tip

+

Check the samples to learn by example.

+
+

I/O

+

Laboratory is nothing more than a high-level API over the FeatureStorage interface responsible for persisting feature flags. All implementations that are provided by this library rely on a feature flag package name and an enum name.

+
+

Warning

+

Because the persistence mechanism relies on package names and enum names, you should be careful when refactoring feature flags already available on production. Changing these options may result in a perception of unsaved feature flags.

+
+

Because FeatureStorage is an interface that is meant to be used with I/O operations, it exposes only suspend functions. Laboratory, on the other hand, allows you to opt-into blocking equivalents of read and write functions. You can selectively do this by applying the @BlockingIoCall annotation or globally by adding a compiler flag.

+
android {
+  kotlinOptions {
+    freeCompilerArgs += [
+        "-Xopt-in=io.mehow.laboratory.BlockingIoCall",
+    ]
+  }
+}
+
+

In either case, a design that relies on non-blocking function calls is preferable.

+

Sources

+

Feature flags, by default, have only a single source for their options. By convention, it is considered to be a local source. However, you might need to have different data sources for feature flags, depending on some runtime conditions or a build variant. For example, you might want to use a local source during debugging and rely on some remote services on production.

+

Let’s say that you want to have a feature flag that has three sources. One local, and two remote ones.

+
+

Info

+

Notice that a feature flag source is also a feature flag. This allows us to change feature flag sources via Laboratory as well.

+
+
enum class PowerType : Feature<PowerType> {
+  Coal,
+  Wind,
+  Solar;
+
+  public override val defaultOption get() = Solar
+
+  @Suppress("UNCHECKED_CAST")
+  override val source = Source::class.java as Class<Feature<*>>
+
+  enum class Source : Feature<Source> {
+    Local,
+    Firebase,
+    Azure;
+
+    public override val defaultOption get() = Firebase
+  }
+}
+
+

If you define multiple sources for a feature flag, you should add a Local option to them. This allows changing feature flag options at runtime from the QA module.

+

This feature flag definition allows configuring Laboratory in a way that it is capable of recognizing that PowerType has different option providers and that the default provider is Firebase.

+

Because the Laboratory only delegates its work to FeatureStorage, it is FeatureStorage that needs to understand how to connect feature flags with their sources. This is possible with a special implementation of this interface that is available as an extension function.

+
val sourcedFeatureStorage = FeatureStorage.sourced(
+  localSource = FeatureStorage.inMemory(),
+  remoteSources = mapOf(
+    "Firebase" to FeatureStorage.inMemory(),
+    "Azure" to FeatureStorage.inMemory(),
+  ),
+)
+
+

sourcedFeatureStorage delegates persistence mechanism to three different storage and is responsible for coordinating a selected source and a current feature flag option.

+

One error-prone thing is that sourcedFeatureStorage relies on strings and source names to use the correct storage. The reason for this is that two different feature flags might share sources partially.

+
+

Tip

+

Using Gradle plugin allows you to avoid this issue with the generation of a custom FeatureStorage that is always up-to-date.

+
+
enum class PowerType : Feature<PowerType> {
+  Coal,
+  Wind,
+  Solar;
+
+  public override val defaultOption get() = Solar
+
+  @Suppress("UNCHECKED_CAST")
+  override val source = Source::class.java as Class<Feature<*>>
+
+  enum class Source : Feature<Source> {
+    Local,
+    Firebase,
+    Azure;
+
+    public override val defaultOption get() = Firebase
+  }
+}
+
+enum class Theme : Feature<PowerType> {
+  Night,
+  Day,
+  Christmas;
+
+  public override val defaultOption get() = Night
+
+  @Suppress("UNCHECKED_CAST")
+  override val source = Source::class.java as Class<Feature<*>>
+
+  enum class Source : Feature<Source> {
+    Local,
+    Azure;
+
+    public override val defaultOption get() = Local
+  }
+}
+
+

In this case, Theme and PowerType feature flags share Azure source, but Firebase applies only to the PowerType flag.

+
// Create laboratory that understands sourced features
+val laboratory = Laboratory.create(sourcedFeatureStorage)
+
+// Check option of PowerType in Firebase FeatureStorage
+val powerTypeFirebaseValue = laboratory.experiment<PowerType>()
+
+// Check option of Theme in local FeatureStorage
+val themeLocalValue = laboratory.experiment<Theme>()
+
+// Set source of Theme source to Azure (PowerType is still unaffected and uses Firebase)
+val success = laboratory.setOption(Theme.Source.Azure)
+
+// Check option of Theme in Azure FeatureStorage
+val themeAzureValue = laboratory.experiment<Theme>()
+
+
+

Info

+

The implementation of sourcedFeatureStorage provided by the library saves data only in localSource.

+
+

To propagate remote feature flag options on updates, they need to be connected to a remote source.

+
enum class ShowAds : Feature<ShowAds> {
+  Enabled,
+  Disabled;
+
+  public override val defaultOption get() = Disabled
+
+  @Suppress("UNCHECKED_CAST")
+  override val source = Source::class.java as Class<Feature<*>>
+
+  enum class Source : Feature<Source> {
+    Local,
+    Remote;
+
+    public override val defaultOption get() = Remote
+  }
+}
+
+val firebaseStorage = FeatureStorage.inMemory()
+val sourcedFeatureStorage = FeatureStorage.sourced(
+  localSource = FeatureStorage.inMemory(),
+  remoteSources = mapOf("Remote" to firebaseStorage),
+)
+
+// During application initialisation
+val laboratory = Laboratory.create(sourcedFeatureStorage)
+remoteService.observeShowAdsFlag()
+    // Some custom mapping between a service option and a feature flag
+    .map { showAds: Boolean ->
+      val showAdsFlag = if (showAds) ShowAds.Enabled else ShowAds.Disabled
+      laboratory.setOption(showAdsFlag)
+    }
+    // Scope should last for the lifetime of an application
+    .launchIn(GlobalScope)
+
+

Default options override

+

Whenever Laboratory reads an option for a feature flag, it falls back to a default option declared on a said flag. However, there might be cases when you’d like to change the default behavior. One example might be having features enabled by default in your debug builds and disabled on production. Or you might use feature flags for configuration, and you’d like to have a different configuration per build variant. Laboratory enables this with default options overrides.

+
enum class ShowAds : Feature<ShowAds> {
+  Enabled,
+  Disabled;
+
+  public override val defaultOption get() = Disabled
+}
+
+object DebugDefaultOptionFactory : DefaultOptionFactory {
+  override fun <T : Feature<T>> create(feature: T): Feature<*>? = when(feature) {
+    is ShowAds -> ShowAds.Enabled
+    else -> null
+  }
+}
+
+val laboratory = Laboratory.builder()
+    .featureStorage(FeatureStorage.inMemory())
+    .defaultOptionFactory(DebugDefaultOptionFactory)
+    .build()
+
+// Uses default option declared in DebugDefaultOptionFactory
+laboratory.experimentIs(ShowAds.Enabled)
+
+

You can be even more creative and, for example, enable all feature flags in your debug builds, which have an option Enabled.

+
class DebugDefaultOptionFactory : DefaultOptionFactory {
+  override fun <T : Feature<T>> create(feature: T): Feature<*>? {
+    return feature.options.associateBy { it.name }["Enabled"]
+  }
+
+  private val <T : Feature<T>> T.options get() = javaClass.options
+}
+
+

Feature flag supervision

+

Feature flags can be supervised using FeatureFlag.supervisorOption property. Whenever supervisor has its option different from the value in this property then the supervised feature flag cannot return any other option than a default one. Option can still be set via Laboratory but it will not be exposed as long as a feature flag is not supervised. This relationship is recursive meaning that grandparents control grandchildren indirectly.

+
enum class ChristmasTheme : Feature<ChristmasTheme> {
+  Enabled,
+  Disabled,
+  ;
+
+  public override val defaultOption get() = Disabled
+}
+
+enum class Greeting : Feature<Greeting> {
+  Hello,
+  HoHoHo,
+  ;
+
+  public override val defaultOption get() = Hello
+
+  public override val supervisorOption get() = ChristmasTheme.Enabled
+}
+
+enum class Background : Feature<Background> {
+  White,
+  Reindeer,
+  Snowman,
+  ;
+
+  public override val defaultOption get() = White
+
+  public override val supervisorOption get() = ChristmasTheme.Enabled
+}
+
+val laboratory = Laboratory.inMemory()
+
+laboratory.setOptions(Greeting.HoHoHo, Background.Reindeer)
+
+laboratory.experimentIs(Greeting.HoHoHo) // false
+laboratory.experimentIs(Background.Reindeer) // false
+
+laboratory.setOption(ChristmasTheme.Enabled)
+
+laboratory.experimentIs(Greeting.HoHoHo) // true
+laboratory.experimentIs(Background.Reindeer) // true
+
+

Listening to remote change

+

Feature flags can be synced with a remote source with a help of OptionFactory. Below is a sample setup using Firebase.

+
enum class ChristmasTheme : Feature<ChristmasTheme> {
+  Enabled,
+  Disabled,
+  ;
+
+  public val override val defaultOption get() = Disabled
+}
+
+enum class ShowAds : Feature<ShowAds> {
+  Enabled,
+  Disabled;
+
+  public override val defaultOption get() = Disabled
+}
+
+object CustomOptionFactory : OptionFactory {
+  private val optionMapping = mapOf<String, (String) -> Feature<*>?>(
+    "ChristmasTheme" to { name -> ChristmasTheme::class.java.options.firstOrNull { it.name == name } },
+    "ShowAds" to { name -> ShowAds::class.java.options.firstOrNull { it.name == name } },
+  )
+
+  override fun create(key: String, name: String) = optionMapping[key]?.invoke(name)
+}
+
+class App : Application {
+  override fun onCreate() {
+    val firebaseStorage = FeatureStorage.inMemory()
+    // Get a reference to a node where feature flags are kept
+    val database = FirebaseDatabase.getInstance().reference.child("featureFlags")
+
+    val featureFlagListener = object : ValueEventListener {
+      override fun onDataChange(snapshot: DataSnapshot) {
+        val newOptions = (snapshot.value as? Map<*, *>)
+            .orEmpty()
+            .mapNotNull { (key, value) ->
+              val stringKey = key as? String ?: return@mapNotNull null
+              val stringValue = value as? String ?: return@mapNotNull null
+              CustomOptionFactory.create(stringKey, stringValue)
+            }
+        // Be cautious with using GlobalScope.
+        GlobalScope.launch { firebaseStorage.setOptions(newOptions) }
+      }
+
+      override fun onCancelled(error: DatabaseError) = Unit
+    }
+
+    database.child("featureFlags").addValueEventListener(featureFlagListener)
+  }
+}
+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file